1 //===- ARMInstrInfo.td - Target Description for ARM Target -*- tablegen -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file describes the ARM instructions in TableGen format.
12 //===----------------------------------------------------------------------===//
14 //===----------------------------------------------------------------------===//
15 // ARM specific DAG Nodes.
19 def SDT_ARMCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>;
20 def SDT_ARMCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>, SDTCisVT<1, i32> ]>;
22 def SDT_ARMSaveCallPC : SDTypeProfile<0, 1, []>;
24 def SDT_ARMcall : SDTypeProfile<0, -1, [SDTCisInt<0>]>;
26 def SDT_ARMCMov : SDTypeProfile<1, 3,
27 [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
30 def SDT_ARMBrcond : SDTypeProfile<0, 2,
31 [SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>]>;
33 def SDT_ARMBrJT : SDTypeProfile<0, 3,
34 [SDTCisPtrTy<0>, SDTCisVT<1, i32>,
37 def SDT_ARMCmp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
39 def SDT_ARMPICAdd : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>,
40 SDTCisPtrTy<1>, SDTCisVT<2, i32>]>;
42 def SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
43 def SDT_ARMEH_SJLJ_Setjmp : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisPtrTy<1>]>;
46 def ARMWrapper : SDNode<"ARMISD::Wrapper", SDTIntUnaryOp>;
47 def ARMWrapperJT : SDNode<"ARMISD::WrapperJT", SDTIntBinOp>;
49 def ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeqStart,
50 [SDNPHasChain, SDNPOutFlag]>;
51 def ARMcallseq_end : SDNode<"ISD::CALLSEQ_END", SDT_ARMCallSeqEnd,
52 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
54 def ARMcall : SDNode<"ARMISD::CALL", SDT_ARMcall,
55 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
56 def ARMcall_pred : SDNode<"ARMISD::CALL_PRED", SDT_ARMcall,
57 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
58 def ARMcall_nolink : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall,
59 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
61 def ARMretflag : SDNode<"ARMISD::RET_FLAG", SDTNone,
62 [SDNPHasChain, SDNPOptInFlag]>;
64 def ARMcmov : SDNode<"ARMISD::CMOV", SDT_ARMCMov,
66 def ARMcneg : SDNode<"ARMISD::CNEG", SDT_ARMCMov,
69 def ARMbrcond : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond,
70 [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
72 def ARMbrjt : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT,
75 def ARMcmp : SDNode<"ARMISD::CMP", SDT_ARMCmp,
78 def ARMcmpZ : SDNode<"ARMISD::CMPZ", SDT_ARMCmp,
79 [SDNPOutFlag,SDNPCommutative]>;
81 def ARMpic_add : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>;
83 def ARMsrl_flag : SDNode<"ARMISD::SRL_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
84 def ARMsra_flag : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
85 def ARMrrx : SDNode<"ARMISD::RRX" , SDTIntUnaryOp, [SDNPInFlag ]>;
87 def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>;
88 def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP", SDT_ARMEH_SJLJ_Setjmp>;
90 //===----------------------------------------------------------------------===//
91 // ARM Instruction Predicate Definitions.
93 def HasV5T : Predicate<"Subtarget->hasV5TOps()">;
94 def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">;
95 def HasV6 : Predicate<"Subtarget->hasV6Ops()">;
96 def HasV6T2 : Predicate<"Subtarget->hasV6T2Ops()">;
97 def HasV7 : Predicate<"Subtarget->hasV7Ops()">;
98 def HasVFP2 : Predicate<"Subtarget->hasVFP2()">;
99 def HasVFP3 : Predicate<"Subtarget->hasVFP3()">;
100 def HasNEON : Predicate<"Subtarget->hasNEON()">;
101 def IsThumb : Predicate<"Subtarget->isThumb()">;
102 def IsThumb1Only : Predicate<"Subtarget->isThumb1Only()">;
103 def IsThumb2 : Predicate<"Subtarget->isThumb2()">;
104 def IsARM : Predicate<"!Subtarget->isThumb()">;
105 def IsDarwin : Predicate<"Subtarget->isTargetDarwin()">;
106 def IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">;
107 def CarryDefIsUnused : Predicate<"!N.getNode()->hasAnyUseOfValue(1)">;
108 def CarryDefIsUsed : Predicate<"N.getNode()->hasAnyUseOfValue(1)">;
110 //===----------------------------------------------------------------------===//
111 // ARM Flag Definitions.
113 class RegConstraint<string C> {
114 string Constraints = C;
117 //===----------------------------------------------------------------------===//
118 // ARM specific transformation functions and pattern fragments.
121 // so_imm_neg_XFORM - Return a so_imm value packed into the format described for
122 // so_imm_neg def below.
123 def so_imm_neg_XFORM : SDNodeXForm<imm, [{
124 return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32);
127 // so_imm_not_XFORM - Return a so_imm value packed into the format described for
128 // so_imm_not def below.
129 def so_imm_not_XFORM : SDNodeXForm<imm, [{
130 return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32);
133 // rot_imm predicate - True if the 32-bit immediate is equal to 8, 16, or 24.
134 def rot_imm : PatLeaf<(i32 imm), [{
135 int32_t v = (int32_t)N->getZExtValue();
136 return v == 8 || v == 16 || v == 24;
139 /// imm1_15 predicate - True if the 32-bit immediate is in the range [1,15].
140 def imm1_15 : PatLeaf<(i32 imm), [{
141 return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 16;
144 /// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31].
145 def imm16_31 : PatLeaf<(i32 imm), [{
146 return (int32_t)N->getZExtValue() >= 16 && (int32_t)N->getZExtValue() < 32;
151 return ARM_AM::getSOImmVal(-(int)N->getZExtValue()) != -1;
152 }], so_imm_neg_XFORM>;
156 return ARM_AM::getSOImmVal(~(int)N->getZExtValue()) != -1;
157 }], so_imm_not_XFORM>;
159 // sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits.
160 def sext_16_node : PatLeaf<(i32 GPR:$a), [{
161 return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17;
164 /// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield
166 def bf_inv_mask_imm : Operand<i32>,
168 uint32_t v = (uint32_t)N->getZExtValue();
171 // there can be 1's on either or both "outsides", all the "inside"
173 unsigned int lsb = 0, msb = 31;
174 while (v & (1 << msb)) --msb;
175 while (v & (1 << lsb)) ++lsb;
176 for (unsigned int i = lsb; i <= msb; ++i) {
182 let PrintMethod = "printBitfieldInvMaskImmOperand";
185 class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
186 class UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>;
188 //===----------------------------------------------------------------------===//
189 // Operand Definitions.
193 def brtarget : Operand<OtherVT>;
195 // A list of registers separated by comma. Used by load/store multiple.
196 def reglist : Operand<i32> {
197 let PrintMethod = "printRegisterList";
200 // An operand for the CONSTPOOL_ENTRY pseudo-instruction.
201 def cpinst_operand : Operand<i32> {
202 let PrintMethod = "printCPInstOperand";
205 def jtblock_operand : Operand<i32> {
206 let PrintMethod = "printJTBlockOperand";
208 def jt2block_operand : Operand<i32> {
209 let PrintMethod = "printJT2BlockOperand";
213 def pclabel : Operand<i32> {
214 let PrintMethod = "printPCLabel";
217 // shifter_operand operands: so_reg and so_imm.
218 def so_reg : Operand<i32>, // reg reg imm
219 ComplexPattern<i32, 3, "SelectShifterOperandReg",
220 [shl,srl,sra,rotr]> {
221 let PrintMethod = "printSORegOperand";
222 let MIOperandInfo = (ops GPR, GPR, i32imm);
225 // so_imm - Match a 32-bit shifter_operand immediate operand, which is an
226 // 8-bit immediate rotated by an arbitrary number of bits. so_imm values are
227 // represented in the imm field in the same 12-bit form that they are encoded
228 // into so_imm instructions: the 8-bit immediate is the least significant bits
229 // [bits 0-7], the 4-bit shift amount is the next 4 bits [bits 8-11].
230 def so_imm : Operand<i32>,
232 return ARM_AM::getSOImmVal(N->getZExtValue()) != -1;
234 let PrintMethod = "printSOImmOperand";
237 // Break so_imm's up into two pieces. This handles immediates with up to 16
238 // bits set in them. This uses so_imm2part to match and so_imm2part_[12] to
239 // get the first/second pieces.
240 def so_imm2part : Operand<i32>,
242 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue());
244 let PrintMethod = "printSOImm2PartOperand";
247 def so_imm2part_1 : SDNodeXForm<imm, [{
248 unsigned V = ARM_AM::getSOImmTwoPartFirst((unsigned)N->getZExtValue());
249 return CurDAG->getTargetConstant(V, MVT::i32);
252 def so_imm2part_2 : SDNodeXForm<imm, [{
253 unsigned V = ARM_AM::getSOImmTwoPartSecond((unsigned)N->getZExtValue());
254 return CurDAG->getTargetConstant(V, MVT::i32);
258 // Define ARM specific addressing modes.
260 // addrmode2 := reg +/- reg shop imm
261 // addrmode2 := reg +/- imm12
263 def addrmode2 : Operand<i32>,
264 ComplexPattern<i32, 3, "SelectAddrMode2", []> {
265 let PrintMethod = "printAddrMode2Operand";
266 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
269 def am2offset : Operand<i32>,
270 ComplexPattern<i32, 2, "SelectAddrMode2Offset", []> {
271 let PrintMethod = "printAddrMode2OffsetOperand";
272 let MIOperandInfo = (ops GPR, i32imm);
275 // addrmode3 := reg +/- reg
276 // addrmode3 := reg +/- imm8
278 def addrmode3 : Operand<i32>,
279 ComplexPattern<i32, 3, "SelectAddrMode3", []> {
280 let PrintMethod = "printAddrMode3Operand";
281 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
284 def am3offset : Operand<i32>,
285 ComplexPattern<i32, 2, "SelectAddrMode3Offset", []> {
286 let PrintMethod = "printAddrMode3OffsetOperand";
287 let MIOperandInfo = (ops GPR, i32imm);
290 // addrmode4 := reg, <mode|W>
292 def addrmode4 : Operand<i32>,
293 ComplexPattern<i32, 2, "", []> {
294 let PrintMethod = "printAddrMode4Operand";
295 let MIOperandInfo = (ops GPR, i32imm);
298 // addrmode5 := reg +/- imm8*4
300 def addrmode5 : Operand<i32>,
301 ComplexPattern<i32, 2, "SelectAddrMode5", []> {
302 let PrintMethod = "printAddrMode5Operand";
303 let MIOperandInfo = (ops GPR, i32imm);
306 // addrmode6 := reg with optional writeback
308 def addrmode6 : Operand<i32>,
309 ComplexPattern<i32, 3, "SelectAddrMode6", []> {
310 let PrintMethod = "printAddrMode6Operand";
311 let MIOperandInfo = (ops GPR:$addr, GPR:$upd, i32imm);
314 // addrmodepc := pc + reg
316 def addrmodepc : Operand<i32>,
317 ComplexPattern<i32, 2, "SelectAddrModePC", []> {
318 let PrintMethod = "printAddrModePCOperand";
319 let MIOperandInfo = (ops GPR, i32imm);
322 //===----------------------------------------------------------------------===//
324 include "ARMInstrFormats.td"
326 //===----------------------------------------------------------------------===//
327 // Multiclass helpers...
330 /// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a
331 /// binop that produces a value.
332 multiclass AsI1_bin_irs<bits<4> opcod, string opc, PatFrag opnode,
333 bit Commutable = 0> {
334 def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
335 opc, " $dst, $a, $b",
336 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> {
339 def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
340 opc, " $dst, $a, $b",
341 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> {
343 let isCommutable = Commutable;
345 def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
346 opc, " $dst, $a, $b",
347 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
352 /// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
353 /// instruction modifies the CSPR register.
354 let Defs = [CPSR] in {
355 multiclass AI1_bin_s_irs<bits<4> opcod, string opc, PatFrag opnode,
356 bit Commutable = 0> {
357 def ri : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
358 opc, "s $dst, $a, $b",
359 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> {
362 def rr : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
363 opc, "s $dst, $a, $b",
364 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> {
365 let isCommutable = Commutable;
368 def rs : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
369 opc, "s $dst, $a, $b",
370 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
376 /// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
377 /// patterns. Similar to AsI1_bin_irs except the instruction does not produce
378 /// a explicit result, only implicitly set CPSR.
379 let Defs = [CPSR] in {
380 multiclass AI1_cmp_irs<bits<4> opcod, string opc, PatFrag opnode,
381 bit Commutable = 0> {
382 def ri : AI1<opcod, (outs), (ins GPR:$a, so_imm:$b), DPFrm,
384 [(opnode GPR:$a, so_imm:$b)]> {
387 def rr : AI1<opcod, (outs), (ins GPR:$a, GPR:$b), DPFrm,
389 [(opnode GPR:$a, GPR:$b)]> {
391 let isCommutable = Commutable;
393 def rs : AI1<opcod, (outs), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
395 [(opnode GPR:$a, so_reg:$b)]> {
401 /// AI_unary_rrot - A unary operation with two forms: one whose operand is a
402 /// register and one whose operand is a register rotated by 8/16/24.
403 /// FIXME: Remove the 'r' variant. Its rot_imm is zero.
404 multiclass AI_unary_rrot<bits<8> opcod, string opc, PatFrag opnode> {
405 def r : AExtI<opcod, (outs GPR:$dst), (ins GPR:$Src),
407 [(set GPR:$dst, (opnode GPR:$Src))]>,
408 Requires<[IsARM, HasV6]> {
409 let Inst{19-16} = 0b1111;
411 def r_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$Src, i32imm:$rot),
412 opc, " $dst, $Src, ror $rot",
413 [(set GPR:$dst, (opnode (rotr GPR:$Src, rot_imm:$rot)))]>,
414 Requires<[IsARM, HasV6]> {
415 let Inst{19-16} = 0b1111;
419 /// AI_bin_rrot - A binary operation with two forms: one whose operand is a
420 /// register and one whose operand is a register rotated by 8/16/24.
421 multiclass AI_bin_rrot<bits<8> opcod, string opc, PatFrag opnode> {
422 def rr : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS),
423 opc, " $dst, $LHS, $RHS",
424 [(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]>,
425 Requires<[IsARM, HasV6]>;
426 def rr_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS, i32imm:$rot),
427 opc, " $dst, $LHS, $RHS, ror $rot",
428 [(set GPR:$dst, (opnode GPR:$LHS,
429 (rotr GPR:$RHS, rot_imm:$rot)))]>,
430 Requires<[IsARM, HasV6]>;
433 /// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
434 let Uses = [CPSR] in {
435 multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
436 bit Commutable = 0> {
437 def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
438 DPFrm, opc, " $dst, $a, $b",
439 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
440 Requires<[IsARM, CarryDefIsUnused]> {
443 def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
444 DPFrm, opc, " $dst, $a, $b",
445 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
446 Requires<[IsARM, CarryDefIsUnused]> {
447 let isCommutable = Commutable;
450 def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
451 DPSoRegFrm, opc, " $dst, $a, $b",
452 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
453 Requires<[IsARM, CarryDefIsUnused]> {
456 // Carry setting variants
457 def Sri : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
458 DPFrm, !strconcat(opc, "s $dst, $a, $b"),
459 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
460 Requires<[IsARM, CarryDefIsUsed]> {
464 def Srr : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
465 DPFrm, !strconcat(opc, "s $dst, $a, $b"),
466 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
467 Requires<[IsARM, CarryDefIsUsed]> {
471 def Srs : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
472 DPSoRegFrm, !strconcat(opc, "s $dst, $a, $b"),
473 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
474 Requires<[IsARM, CarryDefIsUsed]> {
481 //===----------------------------------------------------------------------===//
483 //===----------------------------------------------------------------------===//
485 //===----------------------------------------------------------------------===//
486 // Miscellaneous Instructions.
489 /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in
490 /// the function. The first operand is the ID# for this instruction, the second
491 /// is the index into the MachineConstantPool that this is, the third is the
492 /// size in bytes of this constant pool entry.
493 let neverHasSideEffects = 1, isNotDuplicable = 1 in
494 def CONSTPOOL_ENTRY :
495 PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
497 "${instid:label} ${cpidx:cpentry}", []>;
499 let Defs = [SP], Uses = [SP] in {
501 PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p),
502 "@ ADJCALLSTACKUP $amt1",
503 [(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
505 def ADJCALLSTACKDOWN :
506 PseudoInst<(outs), (ins i32imm:$amt, pred:$p),
507 "@ ADJCALLSTACKDOWN $amt",
508 [(ARMcallseq_start timm:$amt)]>;
512 PseudoInst<(outs), (ins i32imm:$line, i32imm:$col, i32imm:$file),
513 ".loc $file, $line, $col",
514 [(dwarf_loc (i32 imm:$line), (i32 imm:$col), (i32 imm:$file))]>;
517 // Address computation and loads and stores in PIC mode.
518 let isNotDuplicable = 1 in {
519 def PICADD : AXI1<0b0100, (outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
520 Pseudo, "$cp:\n\tadd$p $dst, pc, $a",
521 [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
523 let AddedComplexity = 10 in {
524 let canFoldAsLoad = 1 in
525 def PICLDR : AXI2ldw<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
526 Pseudo, "${addr:label}:\n\tldr$p $dst, $addr",
527 [(set GPR:$dst, (load addrmodepc:$addr))]>;
529 def PICLDRH : AXI3ldh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
530 Pseudo, "${addr:label}:\n\tldr${p}h $dst, $addr",
531 [(set GPR:$dst, (zextloadi16 addrmodepc:$addr))]>;
533 def PICLDRB : AXI2ldb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
534 Pseudo, "${addr:label}:\n\tldr${p}b $dst, $addr",
535 [(set GPR:$dst, (zextloadi8 addrmodepc:$addr))]>;
537 def PICLDRSH : AXI3ldsh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
538 Pseudo, "${addr:label}:\n\tldr${p}sh $dst, $addr",
539 [(set GPR:$dst, (sextloadi16 addrmodepc:$addr))]>;
541 def PICLDRSB : AXI3ldsb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
542 Pseudo, "${addr:label}:\n\tldr${p}sb $dst, $addr",
543 [(set GPR:$dst, (sextloadi8 addrmodepc:$addr))]>;
545 let AddedComplexity = 10 in {
546 def PICSTR : AXI2stw<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
547 Pseudo, "${addr:label}:\n\tstr$p $src, $addr",
548 [(store GPR:$src, addrmodepc:$addr)]>;
550 def PICSTRH : AXI3sth<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
551 Pseudo, "${addr:label}:\n\tstr${p}h $src, $addr",
552 [(truncstorei16 GPR:$src, addrmodepc:$addr)]>;
554 def PICSTRB : AXI2stb<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
555 Pseudo, "${addr:label}:\n\tstr${p}b $src, $addr",
556 [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
558 } // isNotDuplicable = 1
561 // LEApcrel - Load a pc-relative address into a register without offending the
563 def LEApcrel : AXI1<0x0, (outs GPR:$dst), (ins i32imm:$label, pred:$p), Pseudo,
564 !strconcat(!strconcat(".set ${:private}PCRELV${:uid}, ($label-(",
565 "${:private}PCRELL${:uid}+8))\n"),
566 !strconcat("${:private}PCRELL${:uid}:\n\t",
567 "add$p $dst, pc, #${:private}PCRELV${:uid}")),
570 def LEApcrelJT : AXI1<0x0, (outs GPR:$dst),
571 (ins i32imm:$label, i32imm:$id, pred:$p),
573 !strconcat(!strconcat(".set ${:private}PCRELV${:uid}, "
574 "(${label}_${id:no_hash}-(",
575 "${:private}PCRELL${:uid}+8))\n"),
576 !strconcat("${:private}PCRELL${:uid}:\n\t",
577 "add$p $dst, pc, #${:private}PCRELV${:uid}")),
582 //===----------------------------------------------------------------------===//
583 // Control Flow Instructions.
586 let isReturn = 1, isTerminator = 1 in
587 def BX_RET : AI<(outs), (ins), BrMiscFrm, "bx", " lr", [(ARMretflag)]> {
588 let Inst{7-4} = 0b0001;
589 let Inst{19-8} = 0b111111111111;
590 let Inst{27-20} = 0b00010010;
593 // FIXME: remove when we have a way to marking a MI with these properties.
594 // FIXME: $dst1 should be a def. But the extra ops must be in the end of the
596 // FIXME: Should pc be an implicit operand like PICADD, etc?
597 let isReturn = 1, isTerminator = 1, mayLoad = 1 in
598 def LDM_RET : AXI4ld<(outs),
599 (ins addrmode4:$addr, pred:$p, reglist:$dst1, variable_ops),
600 LdStMulFrm, "ldm${p}${addr:submode} $addr, $dst1",
603 // On non-Darwin platforms R9 is callee-saved.
604 let isCall = 1, Itinerary = IIC_Br,
605 Defs = [R0, R1, R2, R3, R12, LR,
606 D0, D1, D2, D3, D4, D5, D6, D7,
607 D16, D17, D18, D19, D20, D21, D22, D23,
608 D24, D25, D26, D27, D28, D29, D31, D31, CPSR] in {
609 def BL : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
611 [(ARMcall tglobaladdr:$func)]>, Requires<[IsNotDarwin]>;
613 def BL_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
614 "bl", " ${func:call}",
615 [(ARMcall_pred tglobaladdr:$func)]>, Requires<[IsNotDarwin]>;
618 def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
620 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsNotDarwin]> {
621 let Inst{7-4} = 0b0011;
622 let Inst{19-8} = 0b111111111111;
623 let Inst{27-20} = 0b00010010;
627 def BX : ABXIx2<(outs), (ins GPR:$func, variable_ops),
628 "mov lr, pc\n\tbx $func",
629 [(ARMcall_nolink GPR:$func)]>, Requires<[IsNotDarwin]> {
630 let Inst{7-4} = 0b0001;
631 let Inst{19-8} = 0b111111111111;
632 let Inst{27-20} = 0b00010010;
636 // On Darwin R9 is call-clobbered.
637 let isCall = 1, Itinerary = IIC_Br,
638 Defs = [R0, R1, R2, R3, R9, R12, LR,
639 D0, D1, D2, D3, D4, D5, D6, D7,
640 D16, D17, D18, D19, D20, D21, D22, D23,
641 D24, D25, D26, D27, D28, D29, D31, D31, CPSR] in {
642 def BLr9 : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
644 [(ARMcall tglobaladdr:$func)]>, Requires<[IsDarwin]>;
646 def BLr9_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
647 "bl", " ${func:call}",
648 [(ARMcall_pred tglobaladdr:$func)]>, Requires<[IsDarwin]>;
651 def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
653 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> {
654 let Inst{7-4} = 0b0011;
655 let Inst{19-8} = 0b111111111111;
656 let Inst{27-20} = 0b00010010;
660 def BXr9 : ABXIx2<(outs), (ins GPR:$func, variable_ops),
661 "mov lr, pc\n\tbx $func",
662 [(ARMcall_nolink GPR:$func)]>, Requires<[IsARM, IsDarwin]> {
663 let Inst{7-4} = 0b0001;
664 let Inst{19-8} = 0b111111111111;
665 let Inst{27-20} = 0b00010010;
669 let isBranch = 1, isTerminator = 1, Itinerary = IIC_Br in {
670 // B is "predicable" since it can be xformed into a Bcc.
671 let isBarrier = 1 in {
672 let isPredicable = 1 in
673 def B : ABXI<0b1010, (outs), (ins brtarget:$target), "b $target",
676 let isNotDuplicable = 1, isIndirectBranch = 1 in {
677 def BR_JTr : JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id),
678 "mov pc, $target \n$jt",
679 [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]> {
680 let Inst{20} = 0; // S Bit
681 let Inst{24-21} = 0b1101;
682 let Inst{27-25} = 0b000;
684 def BR_JTm : JTI<(outs),
685 (ins addrmode2:$target, jtblock_operand:$jt, i32imm:$id),
686 "ldr pc, $target \n$jt",
687 [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
689 let Inst{20} = 1; // L bit
690 let Inst{21} = 0; // W bit
691 let Inst{22} = 0; // B bit
692 let Inst{24} = 1; // P bit
693 let Inst{27-25} = 0b011;
695 def BR_JTadd : JTI<(outs),
696 (ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id),
697 "add pc, $target, $idx \n$jt",
698 [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
700 let Inst{20} = 0; // S bit
701 let Inst{24-21} = 0b0100;
702 let Inst{27-25} = 0b000;
704 } // isNotDuplicable = 1, isIndirectBranch = 1
707 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
708 // a two-value operand where a dag node expects two operands. :(
709 def Bcc : ABI<0b1010, (outs), (ins brtarget:$target),
711 [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]>;
714 //===----------------------------------------------------------------------===//
715 // Load / store Instructions.
719 let canFoldAsLoad = 1 in
720 def LDR : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm,
721 "ldr", " $dst, $addr",
722 [(set GPR:$dst, (load addrmode2:$addr))]>;
724 // Special LDR for loads from non-pc-relative constpools.
725 let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1 in
726 def LDRcp : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm,
727 "ldr", " $dst, $addr", []>;
729 // Loads with zero extension
730 def LDRH : AI3ldh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
731 "ldr", "h $dst, $addr",
732 [(set GPR:$dst, (zextloadi16 addrmode3:$addr))]>;
734 def LDRB : AI2ldb<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm,
735 "ldr", "b $dst, $addr",
736 [(set GPR:$dst, (zextloadi8 addrmode2:$addr))]>;
738 // Loads with sign extension
739 def LDRSH : AI3ldsh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
740 "ldr", "sh $dst, $addr",
741 [(set GPR:$dst, (sextloadi16 addrmode3:$addr))]>;
743 def LDRSB : AI3ldsb<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
744 "ldr", "sb $dst, $addr",
745 [(set GPR:$dst, (sextloadi8 addrmode3:$addr))]>;
749 def LDRD : AI3ldd<(outs GPR:$dst1, GPR:$dst2), (ins addrmode3:$addr), LdMiscFrm,
750 "ldr", "d $dst1, $addr", []>, Requires<[IsARM, HasV5T]>;
753 def LDR_PRE : AI2ldwpr<(outs GPR:$dst, GPR:$base_wb),
754 (ins addrmode2:$addr), LdFrm,
755 "ldr", " $dst, $addr!", "$addr.base = $base_wb", []>;
757 def LDR_POST : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
758 (ins GPR:$base, am2offset:$offset), LdFrm,
759 "ldr", " $dst, [$base], $offset", "$base = $base_wb", []>;
761 def LDRH_PRE : AI3ldhpr<(outs GPR:$dst, GPR:$base_wb),
762 (ins addrmode3:$addr), LdMiscFrm,
763 "ldr", "h $dst, $addr!", "$addr.base = $base_wb", []>;
765 def LDRH_POST : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
766 (ins GPR:$base,am3offset:$offset), LdMiscFrm,
767 "ldr", "h $dst, [$base], $offset", "$base = $base_wb", []>;
769 def LDRB_PRE : AI2ldbpr<(outs GPR:$dst, GPR:$base_wb),
770 (ins addrmode2:$addr), LdFrm,
771 "ldr", "b $dst, $addr!", "$addr.base = $base_wb", []>;
773 def LDRB_POST : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
774 (ins GPR:$base,am2offset:$offset), LdFrm,
775 "ldr", "b $dst, [$base], $offset", "$base = $base_wb", []>;
777 def LDRSH_PRE : AI3ldshpr<(outs GPR:$dst, GPR:$base_wb),
778 (ins addrmode3:$addr), LdMiscFrm,
779 "ldr", "sh $dst, $addr!", "$addr.base = $base_wb", []>;
781 def LDRSH_POST: AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
782 (ins GPR:$base,am3offset:$offset), LdMiscFrm,
783 "ldr", "sh $dst, [$base], $offset", "$base = $base_wb", []>;
785 def LDRSB_PRE : AI3ldsbpr<(outs GPR:$dst, GPR:$base_wb),
786 (ins addrmode3:$addr), LdMiscFrm,
787 "ldr", "sb $dst, $addr!", "$addr.base = $base_wb", []>;
789 def LDRSB_POST: AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
790 (ins GPR:$base,am3offset:$offset), LdMiscFrm,
791 "ldr", "sb $dst, [$base], $offset", "$base = $base_wb", []>;
795 def STR : AI2stw<(outs), (ins GPR:$src, addrmode2:$addr), StFrm,
796 "str", " $src, $addr",
797 [(store GPR:$src, addrmode2:$addr)]>;
799 // Stores with truncate
800 def STRH : AI3sth<(outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm,
801 "str", "h $src, $addr",
802 [(truncstorei16 GPR:$src, addrmode3:$addr)]>;
804 def STRB : AI2stb<(outs), (ins GPR:$src, addrmode2:$addr), StFrm,
805 "str", "b $src, $addr",
806 [(truncstorei8 GPR:$src, addrmode2:$addr)]>;
810 def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),StMiscFrm,
811 "str", "d $src1, $addr", []>, Requires<[IsARM, HasV5T]>;
814 def STR_PRE : AI2stwpr<(outs GPR:$base_wb),
815 (ins GPR:$src, GPR:$base, am2offset:$offset), StFrm,
816 "str", " $src, [$base, $offset]!", "$base = $base_wb",
818 (pre_store GPR:$src, GPR:$base, am2offset:$offset))]>;
820 def STR_POST : AI2stwpo<(outs GPR:$base_wb),
821 (ins GPR:$src, GPR:$base,am2offset:$offset), StFrm,
822 "str", " $src, [$base], $offset", "$base = $base_wb",
824 (post_store GPR:$src, GPR:$base, am2offset:$offset))]>;
826 def STRH_PRE : AI3sthpr<(outs GPR:$base_wb),
827 (ins GPR:$src, GPR:$base,am3offset:$offset), StMiscFrm,
828 "str", "h $src, [$base, $offset]!", "$base = $base_wb",
830 (pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>;
832 def STRH_POST: AI3sthpo<(outs GPR:$base_wb),
833 (ins GPR:$src, GPR:$base,am3offset:$offset), StMiscFrm,
834 "str", "h $src, [$base], $offset", "$base = $base_wb",
835 [(set GPR:$base_wb, (post_truncsti16 GPR:$src,
836 GPR:$base, am3offset:$offset))]>;
838 def STRB_PRE : AI2stbpr<(outs GPR:$base_wb),
839 (ins GPR:$src, GPR:$base,am2offset:$offset), StFrm,
840 "str", "b $src, [$base, $offset]!", "$base = $base_wb",
841 [(set GPR:$base_wb, (pre_truncsti8 GPR:$src,
842 GPR:$base, am2offset:$offset))]>;
844 def STRB_POST: AI2stbpo<(outs GPR:$base_wb),
845 (ins GPR:$src, GPR:$base,am2offset:$offset), StFrm,
846 "str", "b $src, [$base], $offset", "$base = $base_wb",
847 [(set GPR:$base_wb, (post_truncsti8 GPR:$src,
848 GPR:$base, am2offset:$offset))]>;
850 //===----------------------------------------------------------------------===//
851 // Load / store multiple Instructions.
854 // FIXME: $dst1 should be a def.
856 def LDM : AXI4ld<(outs),
857 (ins addrmode4:$addr, pred:$p, reglist:$dst1, variable_ops),
858 LdStMulFrm, "ldm${p}${addr:submode} $addr, $dst1",
862 def STM : AXI4st<(outs),
863 (ins addrmode4:$addr, pred:$p, reglist:$src1, variable_ops),
864 LdStMulFrm, "stm${p}${addr:submode} $addr, $src1",
867 //===----------------------------------------------------------------------===//
868 // Move Instructions.
871 let neverHasSideEffects = 1 in
872 def MOVr : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPFrm,
873 "mov", " $dst, $src", []>, UnaryDP;
874 def MOVs : AsI1<0b1101, (outs GPR:$dst), (ins so_reg:$src), DPSoRegFrm,
875 "mov", " $dst, $src", [(set GPR:$dst, so_reg:$src)]>, UnaryDP;
877 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
878 def MOVi : AsI1<0b1101, (outs GPR:$dst), (ins so_imm:$src), DPFrm,
879 "mov", " $dst, $src", [(set GPR:$dst, so_imm:$src)]>, UnaryDP;
881 def MOVrx : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
882 "mov", " $dst, $src, rrx",
883 [(set GPR:$dst, (ARMrrx GPR:$src))]>, UnaryDP;
885 // These aren't really mov instructions, but we have to define them this way
886 // due to flag operands.
888 let Defs = [CPSR] in {
889 def MOVsrl_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
890 "mov", "s $dst, $src, lsr #1",
891 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP;
892 def MOVsra_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
893 "mov", "s $dst, $src, asr #1",
894 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP;
897 //===----------------------------------------------------------------------===//
898 // Extend Instructions.
903 defm SXTB : AI_unary_rrot<0b01101010,
904 "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
905 defm SXTH : AI_unary_rrot<0b01101011,
906 "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
908 defm SXTAB : AI_bin_rrot<0b01101010,
909 "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
910 defm SXTAH : AI_bin_rrot<0b01101011,
911 "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
913 // TODO: SXT(A){B|H}16
917 let AddedComplexity = 16 in {
918 defm UXTB : AI_unary_rrot<0b01101110,
919 "uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>;
920 defm UXTH : AI_unary_rrot<0b01101111,
921 "uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
922 defm UXTB16 : AI_unary_rrot<0b01101100,
923 "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
925 def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
926 (UXTB16r_rot GPR:$Src, 24)>;
927 def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
928 (UXTB16r_rot GPR:$Src, 8)>;
930 defm UXTAB : AI_bin_rrot<0b01101110, "uxtab",
931 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
932 defm UXTAH : AI_bin_rrot<0b01101111, "uxtah",
933 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
936 // This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
937 //defm UXTAB16 : xxx<"uxtab16", 0xff00ff>;
939 // TODO: UXT(A){B|H}16
941 //===----------------------------------------------------------------------===//
942 // Arithmetic Instructions.
945 defm ADD : AsI1_bin_irs<0b0100, "add",
946 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
947 defm SUB : AsI1_bin_irs<0b0010, "sub",
948 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
950 // ADD and SUB with 's' bit set.
951 defm ADDS : AI1_bin_s_irs<0b0100, "add",
952 BinOpFrag<(addc node:$LHS, node:$RHS)>>;
953 defm SUBS : AI1_bin_s_irs<0b0010, "sub",
954 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
956 defm ADC : AI1_adde_sube_irs<0b0101, "adc",
957 BinOpFrag<(adde node:$LHS, node:$RHS)>, 1>;
958 defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
959 BinOpFrag<(sube node:$LHS, node:$RHS)>>;
961 // These don't define reg/reg forms, because they are handled above.
962 def RSBri : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
963 "rsb", " $dst, $a, $b",
964 [(set GPR:$dst, (sub so_imm:$b, GPR:$a))]>;
966 def RSBrs : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
967 "rsb", " $dst, $a, $b",
968 [(set GPR:$dst, (sub so_reg:$b, GPR:$a))]>;
970 // RSB with 's' bit set.
971 let Defs = [CPSR] in {
972 def RSBSri : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
973 "rsb", "s $dst, $a, $b",
974 [(set GPR:$dst, (subc so_imm:$b, GPR:$a))]>;
975 def RSBSrs : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
976 "rsb", "s $dst, $a, $b",
977 [(set GPR:$dst, (subc so_reg:$b, GPR:$a))]>;
980 let Uses = [CPSR] in {
981 def RSCri : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
982 DPFrm, "rsc", " $dst, $a, $b",
983 [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>,
984 Requires<[IsARM, CarryDefIsUnused]>;
985 def RSCrs : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
986 DPSoRegFrm, "rsc", " $dst, $a, $b",
987 [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>,
988 Requires<[IsARM, CarryDefIsUnused]>;
991 // FIXME: Allow these to be predicated.
992 let Defs = [CPSR], Uses = [CPSR] in {
993 def RSCSri : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
994 DPFrm, "rscs $dst, $a, $b",
995 [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>,
996 Requires<[IsARM, CarryDefIsUnused]>;
997 def RSCSrs : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
998 DPSoRegFrm, "rscs $dst, $a, $b",
999 [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>,
1000 Requires<[IsARM, CarryDefIsUnused]>;
1003 // (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
1004 def : ARMPat<(add GPR:$src, so_imm_neg:$imm),
1005 (SUBri GPR:$src, so_imm_neg:$imm)>;
1007 //def : ARMPat<(addc GPR:$src, so_imm_neg:$imm),
1008 // (SUBSri GPR:$src, so_imm_neg:$imm)>;
1009 //def : ARMPat<(adde GPR:$src, so_imm_neg:$imm),
1010 // (SBCri GPR:$src, so_imm_neg:$imm)>;
1012 // Note: These are implemented in C++ code, because they have to generate
1013 // ADD/SUBrs instructions, which use a complex pattern that a xform function
1015 // (mul X, 2^n+1) -> (add (X << n), X)
1016 // (mul X, 2^n-1) -> (rsb X, (X << n))
1019 //===----------------------------------------------------------------------===//
1020 // Bitwise Instructions.
1023 defm AND : AsI1_bin_irs<0b0000, "and",
1024 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
1025 defm ORR : AsI1_bin_irs<0b1100, "orr",
1026 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
1027 defm EOR : AsI1_bin_irs<0b0001, "eor",
1028 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
1029 defm BIC : AsI1_bin_irs<0b1110, "bic",
1030 BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
1032 def BFC : I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
1033 AddrMode1, Size4Bytes, IndexModeNone, DPFrm,
1034 "bfc", " $dst, $imm", "$src = $dst",
1035 [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
1036 Requires<[IsARM, HasV6T2]> {
1037 let Inst{27-21} = 0b0111110;
1038 let Inst{6-0} = 0b0011111;
1041 def MVNr : AsI1<0b1111, (outs GPR:$dst), (ins GPR:$src), DPFrm,
1042 "mvn", " $dst, $src",
1043 [(set GPR:$dst, (not GPR:$src))]>, UnaryDP;
1044 def MVNs : AsI1<0b1111, (outs GPR:$dst), (ins so_reg:$src), DPSoRegFrm,
1045 "mvn", " $dst, $src",
1046 [(set GPR:$dst, (not so_reg:$src))]>, UnaryDP;
1047 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
1048 def MVNi : AsI1<0b1111, (outs GPR:$dst), (ins so_imm:$imm), DPFrm,
1049 "mvn", " $dst, $imm",
1050 [(set GPR:$dst, so_imm_not:$imm)]>,UnaryDP;
1052 def : ARMPat<(and GPR:$src, so_imm_not:$imm),
1053 (BICri GPR:$src, so_imm_not:$imm)>;
1055 //===----------------------------------------------------------------------===//
1056 // Multiply Instructions.
1059 let isCommutable = 1 in
1060 def MUL : AsMul1I<0b0000000, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1061 "mul", " $dst, $a, $b",
1062 [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>;
1064 def MLA : AsMul1I<0b0000001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1065 "mla", " $dst, $a, $b, $c",
1066 [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>;
1068 def MLS : AMul1I <0b0000011, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1069 "mls", " $dst, $a, $b, $c",
1070 [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>,
1071 Requires<[IsARM, HasV6T2]>;
1073 // Extra precision multiplies with low / high results
1074 let neverHasSideEffects = 1 in {
1075 let isCommutable = 1 in {
1076 def SMULL : AsMul1I<0b0000110, (outs GPR:$ldst, GPR:$hdst),
1077 (ins GPR:$a, GPR:$b),
1078 "smull", " $ldst, $hdst, $a, $b", []>;
1080 def UMULL : AsMul1I<0b0000100, (outs GPR:$ldst, GPR:$hdst),
1081 (ins GPR:$a, GPR:$b),
1082 "umull", " $ldst, $hdst, $a, $b", []>;
1085 // Multiply + accumulate
1086 def SMLAL : AsMul1I<0b0000111, (outs GPR:$ldst, GPR:$hdst),
1087 (ins GPR:$a, GPR:$b),
1088 "smlal", " $ldst, $hdst, $a, $b", []>;
1090 def UMLAL : AsMul1I<0b0000101, (outs GPR:$ldst, GPR:$hdst),
1091 (ins GPR:$a, GPR:$b),
1092 "umlal", " $ldst, $hdst, $a, $b", []>;
1094 def UMAAL : AMul1I <0b0000010, (outs GPR:$ldst, GPR:$hdst),
1095 (ins GPR:$a, GPR:$b),
1096 "umaal", " $ldst, $hdst, $a, $b", []>,
1097 Requires<[IsARM, HasV6]>;
1098 } // neverHasSideEffects
1100 // Most significant word multiply
1101 def SMMUL : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1102 "smmul", " $dst, $a, $b",
1103 [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>,
1104 Requires<[IsARM, HasV6]> {
1105 let Inst{7-4} = 0b0001;
1106 let Inst{15-12} = 0b1111;
1109 def SMMLA : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1110 "smmla", " $dst, $a, $b, $c",
1111 [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>,
1112 Requires<[IsARM, HasV6]> {
1113 let Inst{7-4} = 0b0001;
1117 def SMMLS : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
1118 "smmls", " $dst, $a, $b, $c",
1119 [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]>,
1120 Requires<[IsARM, HasV6]> {
1121 let Inst{7-4} = 0b1101;
1124 multiclass AI_smul<string opc, PatFrag opnode> {
1125 def BB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1126 !strconcat(opc, "bb"), " $dst, $a, $b",
1127 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
1128 (sext_inreg GPR:$b, i16)))]>,
1129 Requires<[IsARM, HasV5TE]> {
1134 def BT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1135 !strconcat(opc, "bt"), " $dst, $a, $b",
1136 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
1137 (sra GPR:$b, (i32 16))))]>,
1138 Requires<[IsARM, HasV5TE]> {
1143 def TB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1144 !strconcat(opc, "tb"), " $dst, $a, $b",
1145 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
1146 (sext_inreg GPR:$b, i16)))]>,
1147 Requires<[IsARM, HasV5TE]> {
1152 def TT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1153 !strconcat(opc, "tt"), " $dst, $a, $b",
1154 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
1155 (sra GPR:$b, (i32 16))))]>,
1156 Requires<[IsARM, HasV5TE]> {
1161 def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1162 !strconcat(opc, "wb"), " $dst, $a, $b",
1163 [(set GPR:$dst, (sra (opnode GPR:$a,
1164 (sext_inreg GPR:$b, i16)), (i32 16)))]>,
1165 Requires<[IsARM, HasV5TE]> {
1170 def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
1171 !strconcat(opc, "wt"), " $dst, $a, $b",
1172 [(set GPR:$dst, (sra (opnode GPR:$a,
1173 (sra GPR:$b, (i32 16))), (i32 16)))]>,
1174 Requires<[IsARM, HasV5TE]> {
1181 multiclass AI_smla<string opc, PatFrag opnode> {
1182 def BB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1183 !strconcat(opc, "bb"), " $dst, $a, $b, $acc",
1184 [(set GPR:$dst, (add GPR:$acc,
1185 (opnode (sext_inreg GPR:$a, i16),
1186 (sext_inreg GPR:$b, i16))))]>,
1187 Requires<[IsARM, HasV5TE]> {
1192 def BT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1193 !strconcat(opc, "bt"), " $dst, $a, $b, $acc",
1194 [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16),
1195 (sra GPR:$b, (i32 16)))))]>,
1196 Requires<[IsARM, HasV5TE]> {
1201 def TB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1202 !strconcat(opc, "tb"), " $dst, $a, $b, $acc",
1203 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
1204 (sext_inreg GPR:$b, i16))))]>,
1205 Requires<[IsARM, HasV5TE]> {
1210 def TT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1211 !strconcat(opc, "tt"), " $dst, $a, $b, $acc",
1212 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
1213 (sra GPR:$b, (i32 16)))))]>,
1214 Requires<[IsARM, HasV5TE]> {
1219 def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1220 !strconcat(opc, "wb"), " $dst, $a, $b, $acc",
1221 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
1222 (sext_inreg GPR:$b, i16)), (i32 16))))]>,
1223 Requires<[IsARM, HasV5TE]> {
1228 def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
1229 !strconcat(opc, "wt"), " $dst, $a, $b, $acc",
1230 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
1231 (sra GPR:$b, (i32 16))), (i32 16))))]>,
1232 Requires<[IsARM, HasV5TE]> {
1238 defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
1239 defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
1241 // TODO: Halfword multiple accumulate long: SMLAL<x><y>
1242 // TODO: Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
1244 //===----------------------------------------------------------------------===//
1245 // Misc. Arithmetic Instructions.
1248 def CLZ : AMiscA1I<0b000010110, (outs GPR:$dst), (ins GPR:$src),
1249 "clz", " $dst, $src",
1250 [(set GPR:$dst, (ctlz GPR:$src))]>, Requires<[IsARM, HasV5T]> {
1251 let Inst{7-4} = 0b0001;
1252 let Inst{11-8} = 0b1111;
1253 let Inst{19-16} = 0b1111;
1256 def REV : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src),
1257 "rev", " $dst, $src",
1258 [(set GPR:$dst, (bswap GPR:$src))]>, Requires<[IsARM, HasV6]> {
1259 let Inst{7-4} = 0b0011;
1260 let Inst{11-8} = 0b1111;
1261 let Inst{19-16} = 0b1111;
1264 def REV16 : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src),
1265 "rev16", " $dst, $src",
1267 (or (and (srl GPR:$src, (i32 8)), 0xFF),
1268 (or (and (shl GPR:$src, (i32 8)), 0xFF00),
1269 (or (and (srl GPR:$src, (i32 8)), 0xFF0000),
1270 (and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>,
1271 Requires<[IsARM, HasV6]> {
1272 let Inst{7-4} = 0b1011;
1273 let Inst{11-8} = 0b1111;
1274 let Inst{19-16} = 0b1111;
1277 def REVSH : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src),
1278 "revsh", " $dst, $src",
1281 (or (srl (and GPR:$src, 0xFF00), (i32 8)),
1282 (shl GPR:$src, (i32 8))), i16))]>,
1283 Requires<[IsARM, HasV6]> {
1284 let Inst{7-4} = 0b1011;
1285 let Inst{11-8} = 0b1111;
1286 let Inst{19-16} = 0b1111;
1289 def PKHBT : AMiscA1I<0b01101000, (outs GPR:$dst),
1290 (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
1291 "pkhbt", " $dst, $src1, $src2, LSL $shamt",
1292 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
1293 (and (shl GPR:$src2, (i32 imm:$shamt)),
1295 Requires<[IsARM, HasV6]> {
1296 let Inst{6-4} = 0b001;
1299 // Alternate cases for PKHBT where identities eliminate some nodes.
1300 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)),
1301 (PKHBT GPR:$src1, GPR:$src2, 0)>;
1302 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$shamt)),
1303 (PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>;
1306 def PKHTB : AMiscA1I<0b01101000, (outs GPR:$dst),
1307 (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
1308 "pkhtb", " $dst, $src1, $src2, ASR $shamt",
1309 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
1310 (and (sra GPR:$src2, imm16_31:$shamt),
1311 0xFFFF)))]>, Requires<[IsARM, HasV6]> {
1312 let Inst{6-4} = 0b101;
1315 // Alternate cases for PKHTB where identities eliminate some nodes. Note that
1316 // a shift amount of 0 is *not legal* here, it is PKHBT instead.
1317 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, (i32 16))),
1318 (PKHTB GPR:$src1, GPR:$src2, 16)>;
1319 def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
1320 (and (srl GPR:$src2, imm1_15:$shamt), 0xFFFF)),
1321 (PKHTB GPR:$src1, GPR:$src2, imm1_15:$shamt)>;
1323 //===----------------------------------------------------------------------===//
1324 // Comparison Instructions...
1327 defm CMP : AI1_cmp_irs<0b1010, "cmp",
1328 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
1329 defm CMN : AI1_cmp_irs<0b1011, "cmn",
1330 BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
1332 // Note that TST/TEQ don't set all the same flags that CMP does!
1333 defm TST : AI1_cmp_irs<0b1000, "tst",
1334 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>, 1>;
1335 defm TEQ : AI1_cmp_irs<0b1001, "teq",
1336 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>, 1>;
1338 defm CMPz : AI1_cmp_irs<0b1010, "cmp",
1339 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
1340 defm CMNz : AI1_cmp_irs<0b1011, "cmn",
1341 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
1343 def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
1344 (CMNri GPR:$src, so_imm_neg:$imm)>;
1346 def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
1347 (CMNri GPR:$src, so_imm_neg:$imm)>;
1350 // Conditional moves
1351 // FIXME: should be able to write a pattern for ARMcmov, but can't use
1352 // a two-value operand where a dag node expects two operands. :(
1353 def MOVCCr : AI1<0b1101, (outs GPR:$dst), (ins GPR:$false, GPR:$true), DPFrm,
1354 "mov", " $dst, $true",
1355 [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>,
1356 RegConstraint<"$false = $dst">, UnaryDP;
1358 def MOVCCs : AI1<0b1101, (outs GPR:$dst),
1359 (ins GPR:$false, so_reg:$true), DPSoRegFrm,
1360 "mov", " $dst, $true",
1361 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_reg:$true, imm:$cc, CCR:$ccr))*/]>,
1362 RegConstraint<"$false = $dst">, UnaryDP;
1364 def MOVCCi : AI1<0b1101, (outs GPR:$dst),
1365 (ins GPR:$false, so_imm:$true), DPFrm,
1366 "mov", " $dst, $true",
1367 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
1368 RegConstraint<"$false = $dst">, UnaryDP;
1371 //===----------------------------------------------------------------------===//
1375 // __aeabi_read_tp preserves the registers r1-r3.
1377 Defs = [R0, R12, LR, CPSR] in {
1378 def TPsoft : ABXI<0b1011, (outs), (ins),
1379 "bl __aeabi_read_tp",
1380 [(set R0, ARMthread_pointer)]>;
1383 //===----------------------------------------------------------------------===//
1384 // SJLJ Exception handling intrinsics
1385 // eh_sjlj_setjmp() is a three instruction sequence to store the return
1386 // address and save #0 in R0 for the non-longjmp case.
1387 // Since by its nature we may be coming from some other function to get
1388 // here, and we're using the stack frame for the containing function to
1389 // save/restore registers, we can't keep anything live in regs across
1390 // the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
1391 // when we get here from a longjmp(). We force everthing out of registers
1392 // except for our own input by listing the relevant registers in Defs. By
1393 // doing so, we also cause the prologue/epilogue code to actively preserve
1394 // all of the callee-saved resgisters, which is exactly what we want.
1396 [ R0, R1, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR,
1397 D0, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
1398 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D31,
1400 def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src),
1401 AddrModeNone, SizeSpecial, IndexModeNone, Pseudo,
1402 "add r0, pc, #4\n\t"
1403 "str r0, [$src, #+4]\n\t"
1404 "mov r0, #0 @ eh_setjmp", "",
1405 [(set R0, (ARMeh_sjlj_setjmp GPR:$src))]>;
1408 //===----------------------------------------------------------------------===//
1409 // Non-Instruction Patterns
1412 // ConstantPool, GlobalAddress, and JumpTable
1413 def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>;
1414 def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>;
1415 def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
1416 (LEApcrelJT tjumptable:$dst, imm:$id)>;
1418 // Large immediate handling.
1420 // Two piece so_imms.
1421 let isReMaterializable = 1 in
1422 def MOVi2pieces : AI1x2<(outs GPR:$dst), (ins so_imm2part:$src), Pseudo,
1423 "mov", " $dst, $src",
1424 [(set GPR:$dst, so_imm2part:$src)]>;
1426 def : ARMPat<(or GPR:$LHS, so_imm2part:$RHS),
1427 (ORRri (ORRri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
1428 (so_imm2part_2 imm:$RHS))>;
1429 def : ARMPat<(xor GPR:$LHS, so_imm2part:$RHS),
1430 (EORri (EORri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
1431 (so_imm2part_2 imm:$RHS))>;
1433 // TODO: add,sub,and, 3-instr forms?
1437 def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>,
1438 Requires<[IsNotDarwin]>;
1439 def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>,
1440 Requires<[IsDarwin]>;
1442 // zextload i1 -> zextload i8
1443 def : ARMPat<(zextloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>;
1445 // extload -> zextload
1446 def : ARMPat<(extloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>;
1447 def : ARMPat<(extloadi8 addrmode2:$addr), (LDRB addrmode2:$addr)>;
1448 def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>;
1450 def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>;
1451 def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>;
1454 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
1455 (sra (shl GPR:$b, (i32 16)), (i32 16))),
1456 (SMULBB GPR:$a, GPR:$b)>;
1457 def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b),
1458 (SMULBB GPR:$a, GPR:$b)>;
1459 def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
1460 (sra GPR:$b, (i32 16))),
1461 (SMULBT GPR:$a, GPR:$b)>;
1462 def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))),
1463 (SMULBT GPR:$a, GPR:$b)>;
1464 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)),
1465 (sra (shl GPR:$b, (i32 16)), (i32 16))),
1466 (SMULTB GPR:$a, GPR:$b)>;
1467 def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b),
1468 (SMULTB GPR:$a, GPR:$b)>;
1469 def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
1471 (SMULWB GPR:$a, GPR:$b)>;
1472 def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)),
1473 (SMULWB GPR:$a, GPR:$b)>;
1475 def : ARMV5TEPat<(add GPR:$acc,
1476 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
1477 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
1478 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
1479 def : ARMV5TEPat<(add GPR:$acc,
1480 (mul sext_16_node:$a, sext_16_node:$b)),
1481 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>;
1482 def : ARMV5TEPat<(add GPR:$acc,
1483 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)),
1484 (sra GPR:$b, (i32 16)))),
1485 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
1486 def : ARMV5TEPat<(add GPR:$acc,
1487 (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))),
1488 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>;
1489 def : ARMV5TEPat<(add GPR:$acc,
1490 (mul (sra GPR:$a, (i32 16)),
1491 (sra (shl GPR:$b, (i32 16)), (i32 16)))),
1492 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
1493 def : ARMV5TEPat<(add GPR:$acc,
1494 (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)),
1495 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>;
1496 def : ARMV5TEPat<(add GPR:$acc,
1497 (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))),
1499 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
1500 def : ARMV5TEPat<(add GPR:$acc,
1501 (sra (mul GPR:$a, sext_16_node:$b), (i32 16))),
1502 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>;
1504 //===----------------------------------------------------------------------===//
1508 include "ARMInstrThumb.td"
1510 //===----------------------------------------------------------------------===//
1514 include "ARMInstrThumb2.td"
1516 //===----------------------------------------------------------------------===//
1517 // Floating Point Support
1520 include "ARMInstrVFP.td"
1522 //===----------------------------------------------------------------------===//
1523 // Advanced SIMD (NEON) Support
1526 include "ARMInstrNEON.td"