1 //===-- ARMISelDAGToDAG.cpp - A dag to dag inst selector for ARM ----------===//
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 defines an instruction selector for the ARM target.
12 //===----------------------------------------------------------------------===//
15 #include "ARMISelLowering.h"
16 #include "ARMTargetMachine.h"
17 #include "ARMAddressingModes.h"
18 #include "llvm/CallingConv.h"
19 #include "llvm/Constants.h"
20 #include "llvm/DerivedTypes.h"
21 #include "llvm/Function.h"
22 #include "llvm/Intrinsics.h"
23 #include "llvm/CodeGen/MachineFrameInfo.h"
24 #include "llvm/CodeGen/MachineFunction.h"
25 #include "llvm/CodeGen/MachineInstrBuilder.h"
26 #include "llvm/CodeGen/SelectionDAG.h"
27 #include "llvm/CodeGen/SelectionDAGISel.h"
28 #include "llvm/Target/TargetLowering.h"
29 #include "llvm/Target/TargetOptions.h"
30 #include "llvm/Support/Debug.h"
33 //===--------------------------------------------------------------------===//
34 /// ARMDAGToDAGISel - ARM specific code to select ARM machine
35 /// instructions for SelectionDAG operations.
38 class ARMDAGToDAGISel
: public SelectionDAGISel
{
39 ARMTargetLowering Lowering
;
41 /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
42 /// make the right decision when generating code for different targets.
43 const ARMSubtarget
*Subtarget
;
46 ARMDAGToDAGISel(ARMTargetMachine
&TM
)
47 : SelectionDAGISel(Lowering
), Lowering(TM
),
48 Subtarget(&TM
.getSubtarget
<ARMSubtarget
>()) {
51 virtual const char *getPassName() const {
52 return "ARM Instruction Selection";
55 SDNode
*Select(SDOperand Op
);
56 virtual void InstructionSelectBasicBlock(SelectionDAG
&DAG
);
57 bool SelectAddrMode2(SDOperand Op
, SDOperand N
, SDOperand
&Base
,
58 SDOperand
&Offset
, SDOperand
&Opc
);
59 bool SelectAddrMode2Offset(SDOperand Op
, SDOperand N
,
60 SDOperand
&Offset
, SDOperand
&Opc
);
61 bool SelectAddrMode3(SDOperand Op
, SDOperand N
, SDOperand
&Base
,
62 SDOperand
&Offset
, SDOperand
&Opc
);
63 bool SelectAddrMode3Offset(SDOperand Op
, SDOperand N
,
64 SDOperand
&Offset
, SDOperand
&Opc
);
65 bool SelectAddrMode5(SDOperand Op
, SDOperand N
, SDOperand
&Base
,
68 bool SelectAddrModePC(SDOperand Op
, SDOperand N
, SDOperand
&Offset
,
71 bool SelectThumbAddrModeRR(SDOperand Op
, SDOperand N
, SDOperand
&Base
,
73 bool SelectThumbAddrModeRI5(SDOperand Op
, SDOperand N
, unsigned Scale
,
74 SDOperand
&Base
, SDOperand
&OffImm
,
76 bool SelectThumbAddrModeS1(SDOperand Op
, SDOperand N
, SDOperand
&Base
,
77 SDOperand
&OffImm
, SDOperand
&Offset
);
78 bool SelectThumbAddrModeS2(SDOperand Op
, SDOperand N
, SDOperand
&Base
,
79 SDOperand
&OffImm
, SDOperand
&Offset
);
80 bool SelectThumbAddrModeS4(SDOperand Op
, SDOperand N
, SDOperand
&Base
,
81 SDOperand
&OffImm
, SDOperand
&Offset
);
82 bool SelectThumbAddrModeSP(SDOperand Op
, SDOperand N
, SDOperand
&Base
,
85 bool SelectShifterOperandReg(SDOperand Op
, SDOperand N
, SDOperand
&A
,
86 SDOperand
&B
, SDOperand
&C
);
88 // Include the pieces autogenerated from the target description.
89 #include "ARMGenDAGISel.inc"
93 void ARMDAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG
&DAG
) {
96 DAG
.setRoot(SelectRoot(DAG
.getRoot()));
97 DAG
.RemoveDeadNodes();
99 ScheduleAndEmitDAG(DAG
);
102 bool ARMDAGToDAGISel::SelectAddrMode2(SDOperand Op
, SDOperand N
,
103 SDOperand
&Base
, SDOperand
&Offset
,
105 if (N
.getOpcode() == ISD::MUL
) {
106 if (ConstantSDNode
*RHS
= dyn_cast
<ConstantSDNode
>(N
.getOperand(1))) {
107 // X * [3,5,9] -> X + X * [2,4,8] etc.
108 int RHSC
= (int)RHS
->getValue();
111 ARM_AM::AddrOpc AddSub
= ARM_AM::add
;
113 AddSub
= ARM_AM::sub
;
116 if (isPowerOf2_32(RHSC
)) {
117 unsigned ShAmt
= Log2_32(RHSC
);
118 Base
= Offset
= N
.getOperand(0);
119 Opc
= CurDAG
->getTargetConstant(ARM_AM::getAM2Opc(AddSub
, ShAmt
,
128 if (N
.getOpcode() != ISD::ADD
&& N
.getOpcode() != ISD::SUB
) {
130 if (N
.getOpcode() == ISD::FrameIndex
) {
131 int FI
= cast
<FrameIndexSDNode
>(N
)->getIndex();
132 Base
= CurDAG
->getTargetFrameIndex(FI
, TLI
.getPointerTy());
133 } else if (N
.getOpcode() == ARMISD::Wrapper
) {
134 Base
= N
.getOperand(0);
136 Offset
= CurDAG
->getRegister(0, MVT::i32
);
137 Opc
= CurDAG
->getTargetConstant(ARM_AM::getAM2Opc(ARM_AM::add
, 0,
143 // Match simple R +/- imm12 operands.
144 if (N
.getOpcode() == ISD::ADD
)
145 if (ConstantSDNode
*RHS
= dyn_cast
<ConstantSDNode
>(N
.getOperand(1))) {
146 int RHSC
= (int)RHS
->getValue();
147 if ((RHSC
>= 0 && RHSC
< 0x1000) ||
148 (RHSC
< 0 && RHSC
> -0x1000)) { // 12 bits.
149 Base
= N
.getOperand(0);
150 if (Base
.getOpcode() == ISD::FrameIndex
) {
151 int FI
= cast
<FrameIndexSDNode
>(Base
)->getIndex();
152 Base
= CurDAG
->getTargetFrameIndex(FI
, TLI
.getPointerTy());
154 Offset
= CurDAG
->getRegister(0, MVT::i32
);
156 ARM_AM::AddrOpc AddSub
= ARM_AM::add
;
158 AddSub
= ARM_AM::sub
;
161 Opc
= CurDAG
->getTargetConstant(ARM_AM::getAM2Opc(AddSub
, RHSC
,
168 // Otherwise this is R +/- [possibly shifted] R
169 ARM_AM::AddrOpc AddSub
= N
.getOpcode() == ISD::ADD
? ARM_AM::add
:ARM_AM::sub
;
170 ARM_AM::ShiftOpc ShOpcVal
= ARM_AM::getShiftOpcForNode(N
.getOperand(1));
173 Base
= N
.getOperand(0);
174 Offset
= N
.getOperand(1);
176 if (ShOpcVal
!= ARM_AM::no_shift
) {
177 // Check to see if the RHS of the shift is a constant, if not, we can't fold
179 if (ConstantSDNode
*Sh
=
180 dyn_cast
<ConstantSDNode
>(N
.getOperand(1).getOperand(1))) {
181 ShAmt
= Sh
->getValue();
182 Offset
= N
.getOperand(1).getOperand(0);
184 ShOpcVal
= ARM_AM::no_shift
;
188 // Try matching (R shl C) + (R).
189 if (N
.getOpcode() == ISD::ADD
&& ShOpcVal
== ARM_AM::no_shift
) {
190 ShOpcVal
= ARM_AM::getShiftOpcForNode(N
.getOperand(0));
191 if (ShOpcVal
!= ARM_AM::no_shift
) {
192 // Check to see if the RHS of the shift is a constant, if not, we can't
194 if (ConstantSDNode
*Sh
=
195 dyn_cast
<ConstantSDNode
>(N
.getOperand(0).getOperand(1))) {
196 ShAmt
= Sh
->getValue();
197 Offset
= N
.getOperand(0).getOperand(0);
198 Base
= N
.getOperand(1);
200 ShOpcVal
= ARM_AM::no_shift
;
205 Opc
= CurDAG
->getTargetConstant(ARM_AM::getAM2Opc(AddSub
, ShAmt
, ShOpcVal
),
210 bool ARMDAGToDAGISel::SelectAddrMode2Offset(SDOperand Op
, SDOperand N
,
211 SDOperand
&Offset
, SDOperand
&Opc
) {
212 unsigned Opcode
= Op
.getOpcode();
213 ISD::MemIndexedMode AM
= (Opcode
== ISD::LOAD
)
214 ? cast
<LoadSDNode
>(Op
)->getAddressingMode()
215 : cast
<StoreSDNode
>(Op
)->getAddressingMode();
216 ARM_AM::AddrOpc AddSub
= (AM
== ISD::PRE_INC
|| AM
== ISD::POST_INC
)
217 ? ARM_AM::add
: ARM_AM::sub
;
218 if (ConstantSDNode
*C
= dyn_cast
<ConstantSDNode
>(N
)) {
219 int Val
= (int)C
->getValue();
220 if (Val
>= 0 && Val
< 0x1000) { // 12 bits.
221 Offset
= CurDAG
->getRegister(0, MVT::i32
);
222 Opc
= CurDAG
->getTargetConstant(ARM_AM::getAM2Opc(AddSub
, Val
,
230 ARM_AM::ShiftOpc ShOpcVal
= ARM_AM::getShiftOpcForNode(N
);
232 if (ShOpcVal
!= ARM_AM::no_shift
) {
233 // Check to see if the RHS of the shift is a constant, if not, we can't fold
235 if (ConstantSDNode
*Sh
= dyn_cast
<ConstantSDNode
>(N
.getOperand(1))) {
236 ShAmt
= Sh
->getValue();
237 Offset
= N
.getOperand(0);
239 ShOpcVal
= ARM_AM::no_shift
;
243 Opc
= CurDAG
->getTargetConstant(ARM_AM::getAM2Opc(AddSub
, ShAmt
, ShOpcVal
),
249 bool ARMDAGToDAGISel::SelectAddrMode3(SDOperand Op
, SDOperand N
,
250 SDOperand
&Base
, SDOperand
&Offset
,
252 if (N
.getOpcode() == ISD::SUB
) {
253 // X - C is canonicalize to X + -C, no need to handle it here.
254 Base
= N
.getOperand(0);
255 Offset
= N
.getOperand(1);
256 Opc
= CurDAG
->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::sub
, 0),MVT::i32
);
260 if (N
.getOpcode() != ISD::ADD
) {
262 if (N
.getOpcode() == ISD::FrameIndex
) {
263 int FI
= cast
<FrameIndexSDNode
>(N
)->getIndex();
264 Base
= CurDAG
->getTargetFrameIndex(FI
, TLI
.getPointerTy());
266 Offset
= CurDAG
->getRegister(0, MVT::i32
);
267 Opc
= CurDAG
->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::add
, 0),MVT::i32
);
271 // If the RHS is +/- imm8, fold into addr mode.
272 if (ConstantSDNode
*RHS
= dyn_cast
<ConstantSDNode
>(N
.getOperand(1))) {
273 int RHSC
= (int)RHS
->getValue();
274 if ((RHSC
>= 0 && RHSC
< 256) ||
275 (RHSC
< 0 && RHSC
> -256)) { // note -256 itself isn't allowed.
276 Base
= N
.getOperand(0);
277 if (Base
.getOpcode() == ISD::FrameIndex
) {
278 int FI
= cast
<FrameIndexSDNode
>(Base
)->getIndex();
279 Base
= CurDAG
->getTargetFrameIndex(FI
, TLI
.getPointerTy());
281 Offset
= CurDAG
->getRegister(0, MVT::i32
);
283 ARM_AM::AddrOpc AddSub
= ARM_AM::add
;
285 AddSub
= ARM_AM::sub
;
288 Opc
= CurDAG
->getTargetConstant(ARM_AM::getAM3Opc(AddSub
, RHSC
),MVT::i32
);
293 Base
= N
.getOperand(0);
294 Offset
= N
.getOperand(1);
295 Opc
= CurDAG
->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::add
, 0), MVT::i32
);
299 bool ARMDAGToDAGISel::SelectAddrMode3Offset(SDOperand Op
, SDOperand N
,
300 SDOperand
&Offset
, SDOperand
&Opc
) {
301 unsigned Opcode
= Op
.getOpcode();
302 ISD::MemIndexedMode AM
= (Opcode
== ISD::LOAD
)
303 ? cast
<LoadSDNode
>(Op
)->getAddressingMode()
304 : cast
<StoreSDNode
>(Op
)->getAddressingMode();
305 ARM_AM::AddrOpc AddSub
= (AM
== ISD::PRE_INC
|| AM
== ISD::POST_INC
)
306 ? ARM_AM::add
: ARM_AM::sub
;
307 if (ConstantSDNode
*C
= dyn_cast
<ConstantSDNode
>(N
)) {
308 int Val
= (int)C
->getValue();
309 if (Val
>= 0 && Val
< 256) {
310 Offset
= CurDAG
->getRegister(0, MVT::i32
);
311 Opc
= CurDAG
->getTargetConstant(ARM_AM::getAM3Opc(AddSub
, Val
), MVT::i32
);
317 Opc
= CurDAG
->getTargetConstant(ARM_AM::getAM3Opc(AddSub
, 0), MVT::i32
);
322 bool ARMDAGToDAGISel::SelectAddrMode5(SDOperand Op
, SDOperand N
,
323 SDOperand
&Base
, SDOperand
&Offset
) {
324 if (N
.getOpcode() != ISD::ADD
) {
326 if (N
.getOpcode() == ISD::FrameIndex
) {
327 int FI
= cast
<FrameIndexSDNode
>(N
)->getIndex();
328 Base
= CurDAG
->getTargetFrameIndex(FI
, TLI
.getPointerTy());
329 } else if (N
.getOpcode() == ARMISD::Wrapper
) {
330 Base
= N
.getOperand(0);
332 Offset
= CurDAG
->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::add
, 0),
337 // If the RHS is +/- imm8, fold into addr mode.
338 if (ConstantSDNode
*RHS
= dyn_cast
<ConstantSDNode
>(N
.getOperand(1))) {
339 int RHSC
= (int)RHS
->getValue();
340 if ((RHSC
& 3) == 0) { // The constant is implicitly multiplied by 4.
342 if ((RHSC
>= 0 && RHSC
< 256) ||
343 (RHSC
< 0 && RHSC
> -256)) { // note -256 itself isn't allowed.
344 Base
= N
.getOperand(0);
345 if (Base
.getOpcode() == ISD::FrameIndex
) {
346 int FI
= cast
<FrameIndexSDNode
>(Base
)->getIndex();
347 Base
= CurDAG
->getTargetFrameIndex(FI
, TLI
.getPointerTy());
350 ARM_AM::AddrOpc AddSub
= ARM_AM::add
;
352 AddSub
= ARM_AM::sub
;
355 Offset
= CurDAG
->getTargetConstant(ARM_AM::getAM5Opc(AddSub
, RHSC
),
363 Offset
= CurDAG
->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::add
, 0),
368 bool ARMDAGToDAGISel::SelectAddrModePC(SDOperand Op
, SDOperand N
,
369 SDOperand
&Offset
, SDOperand
&Label
) {
370 if (N
.getOpcode() == ARMISD::PIC_ADD
&& N
.hasOneUse()) {
371 Offset
= N
.getOperand(0);
372 SDOperand N1
= N
.getOperand(1);
373 Label
= CurDAG
->getTargetConstant(cast
<ConstantSDNode
>(N1
)->getValue(),
380 bool ARMDAGToDAGISel::SelectThumbAddrModeRR(SDOperand Op
, SDOperand N
,
381 SDOperand
&Base
, SDOperand
&Offset
){
382 if (N
.getOpcode() != ISD::ADD
) {
384 // We must materialize a zero in a reg! Returning an constant here won't
385 // work since its node is -1 so it won't get added to the selection queue.
386 // Explicitly issue a tMOVri8 node!
387 Offset
= SDOperand(CurDAG
->getTargetNode(ARM::tMOVi8
, MVT::i32
,
388 CurDAG
->getTargetConstant(0, MVT::i32
)), 0);
392 Base
= N
.getOperand(0);
393 Offset
= N
.getOperand(1);
398 ARMDAGToDAGISel::SelectThumbAddrModeRI5(SDOperand Op
, SDOperand N
,
399 unsigned Scale
, SDOperand
&Base
,
400 SDOperand
&OffImm
, SDOperand
&Offset
) {
402 SDOperand TmpBase
, TmpOffImm
;
403 if (SelectThumbAddrModeSP(Op
, N
, TmpBase
, TmpOffImm
))
404 return false; // We want to select tLDRspi / tSTRspi instead.
405 if (N
.getOpcode() == ARMISD::Wrapper
&&
406 N
.getOperand(0).getOpcode() == ISD::TargetConstantPool
)
407 return false; // We want to select tLDRpci instead.
410 if (N
.getOpcode() != ISD::ADD
) {
411 Base
= (N
.getOpcode() == ARMISD::Wrapper
) ? N
.getOperand(0) : N
;
412 Offset
= CurDAG
->getRegister(0, MVT::i32
);
413 OffImm
= CurDAG
->getTargetConstant(0, MVT::i32
);
417 // Thumb does not have [sp, r] address mode.
418 RegisterSDNode
*LHSR
= dyn_cast
<RegisterSDNode
>(N
.getOperand(0));
419 RegisterSDNode
*RHSR
= dyn_cast
<RegisterSDNode
>(N
.getOperand(1));
420 if ((LHSR
&& LHSR
->getReg() == ARM::SP
) ||
421 (RHSR
&& RHSR
->getReg() == ARM::SP
)) {
423 Offset
= CurDAG
->getRegister(0, MVT::i32
);
424 OffImm
= CurDAG
->getTargetConstant(0, MVT::i32
);
428 // If the RHS is + imm5 * scale, fold into addr mode.
429 if (ConstantSDNode
*RHS
= dyn_cast
<ConstantSDNode
>(N
.getOperand(1))) {
430 int RHSC
= (int)RHS
->getValue();
431 if ((RHSC
& (Scale
-1)) == 0) { // The constant is implicitly multiplied.
433 if (RHSC
>= 0 && RHSC
< 32) {
434 Base
= N
.getOperand(0);
435 Offset
= CurDAG
->getRegister(0, MVT::i32
);
436 OffImm
= CurDAG
->getTargetConstant(RHSC
, MVT::i32
);
442 Base
= N
.getOperand(0);
443 Offset
= N
.getOperand(1);
444 OffImm
= CurDAG
->getTargetConstant(0, MVT::i32
);
448 bool ARMDAGToDAGISel::SelectThumbAddrModeS1(SDOperand Op
, SDOperand N
,
449 SDOperand
&Base
, SDOperand
&OffImm
,
451 return SelectThumbAddrModeRI5(Op
, N
, 1, Base
, OffImm
, Offset
);
454 bool ARMDAGToDAGISel::SelectThumbAddrModeS2(SDOperand Op
, SDOperand N
,
455 SDOperand
&Base
, SDOperand
&OffImm
,
457 return SelectThumbAddrModeRI5(Op
, N
, 2, Base
, OffImm
, Offset
);
460 bool ARMDAGToDAGISel::SelectThumbAddrModeS4(SDOperand Op
, SDOperand N
,
461 SDOperand
&Base
, SDOperand
&OffImm
,
463 return SelectThumbAddrModeRI5(Op
, N
, 4, Base
, OffImm
, Offset
);
466 bool ARMDAGToDAGISel::SelectThumbAddrModeSP(SDOperand Op
, SDOperand N
,
467 SDOperand
&Base
, SDOperand
&OffImm
) {
468 if (N
.getOpcode() == ISD::FrameIndex
) {
469 int FI
= cast
<FrameIndexSDNode
>(N
)->getIndex();
470 Base
= CurDAG
->getTargetFrameIndex(FI
, TLI
.getPointerTy());
471 OffImm
= CurDAG
->getTargetConstant(0, MVT::i32
);
475 if (N
.getOpcode() != ISD::ADD
)
478 RegisterSDNode
*LHSR
= dyn_cast
<RegisterSDNode
>(N
.getOperand(0));
479 if (N
.getOperand(0).getOpcode() == ISD::FrameIndex
||
480 (LHSR
&& LHSR
->getReg() == ARM::SP
)) {
481 // If the RHS is + imm8 * scale, fold into addr mode.
482 if (ConstantSDNode
*RHS
= dyn_cast
<ConstantSDNode
>(N
.getOperand(1))) {
483 int RHSC
= (int)RHS
->getValue();
484 if ((RHSC
& 3) == 0) { // The constant is implicitly multiplied.
486 if (RHSC
>= 0 && RHSC
< 256) {
487 Base
= N
.getOperand(0);
488 if (Base
.getOpcode() == ISD::FrameIndex
) {
489 int FI
= cast
<FrameIndexSDNode
>(Base
)->getIndex();
490 Base
= CurDAG
->getTargetFrameIndex(FI
, TLI
.getPointerTy());
492 OffImm
= CurDAG
->getTargetConstant(RHSC
, MVT::i32
);
502 bool ARMDAGToDAGISel::SelectShifterOperandReg(SDOperand Op
,
507 ARM_AM::ShiftOpc ShOpcVal
= ARM_AM::getShiftOpcForNode(N
);
509 // Don't match base register only case. That is matched to a separate
510 // lower complexity pattern with explicit register operand.
511 if (ShOpcVal
== ARM_AM::no_shift
) return false;
513 BaseReg
= N
.getOperand(0);
514 unsigned ShImmVal
= 0;
515 if (ConstantSDNode
*RHS
= dyn_cast
<ConstantSDNode
>(N
.getOperand(1))) {
516 ShReg
= CurDAG
->getRegister(0, MVT::i32
);
517 ShImmVal
= RHS
->getValue() & 31;
519 ShReg
= N
.getOperand(1);
521 Opc
= CurDAG
->getTargetConstant(ARM_AM::getSORegOpc(ShOpcVal
, ShImmVal
),
526 /// getAL - Returns a ARMCC::AL immediate node.
527 static inline SDOperand
getAL(SelectionDAG
*CurDAG
) {
528 return CurDAG
->getTargetConstant((uint64_t)ARMCC::AL
, MVT::i32
);
532 SDNode
*ARMDAGToDAGISel::Select(SDOperand Op
) {
534 unsigned Opcode
= N
->getOpcode();
536 if (Opcode
>= ISD::BUILTIN_OP_END
&& Opcode
< ARMISD::FIRST_NUMBER
)
537 return NULL
; // Already selected.
539 switch (N
->getOpcode()) {
541 case ISD::Constant
: {
542 unsigned Val
= cast
<ConstantSDNode
>(N
)->getValue();
544 if (Subtarget
->isThumb())
545 UseCP
= (Val
> 255 && // MOV
546 ~Val
> 255 && // MOV + MVN
547 !ARM_AM::isThumbImmShiftedVal(Val
)); // MOV + LSL
549 UseCP
= (ARM_AM::getSOImmVal(Val
) == -1 && // MOV
550 ARM_AM::getSOImmVal(~Val
) == -1 && // MVN
551 !ARM_AM::isSOImmTwoPartVal(Val
)); // two instrs.
554 CurDAG
->getTargetConstantPool(ConstantInt::get(Type::Int32Ty
, Val
),
558 if (Subtarget
->isThumb())
559 ResNode
= CurDAG
->getTargetNode(ARM::tLDRcp
, MVT::i32
, MVT::Other
,
560 CPIdx
, CurDAG
->getEntryNode());
564 CurDAG
->getRegister(0, MVT::i32
),
565 CurDAG
->getTargetConstant(0, MVT::i32
),
567 CurDAG
->getRegister(0, MVT::i32
),
568 CurDAG
->getEntryNode()
570 ResNode
=CurDAG
->getTargetNode(ARM::LDRcp
, MVT::i32
, MVT::Other
, Ops
, 6);
572 ReplaceUses(Op
, SDOperand(ResNode
, 0));
576 // Other cases are autogenerated.
579 case ISD::FrameIndex
: {
580 // Selects to ADDri FI, 0 which in turn will become ADDri SP, imm.
581 int FI
= cast
<FrameIndexSDNode
>(N
)->getIndex();
582 SDOperand TFI
= CurDAG
->getTargetFrameIndex(FI
, TLI
.getPointerTy());
583 if (Subtarget
->isThumb())
584 return CurDAG
->SelectNodeTo(N
, ARM::tADDrSPi
, MVT::i32
, TFI
,
585 CurDAG
->getTargetConstant(0, MVT::i32
));
587 SDOperand Ops
[] = { TFI
, CurDAG
->getTargetConstant(0, MVT::i32
),
588 getAL(CurDAG
), CurDAG
->getRegister(0, MVT::i32
),
589 CurDAG
->getRegister(0, MVT::i32
) };
590 return CurDAG
->SelectNodeTo(N
, ARM::ADDri
, MVT::i32
, Ops
, 5);
594 // Select add sp, c to tADDhirr.
595 SDOperand N0
= Op
.getOperand(0);
596 SDOperand N1
= Op
.getOperand(1);
597 RegisterSDNode
*LHSR
= dyn_cast
<RegisterSDNode
>(Op
.getOperand(0));
598 RegisterSDNode
*RHSR
= dyn_cast
<RegisterSDNode
>(Op
.getOperand(1));
599 if (LHSR
&& LHSR
->getReg() == ARM::SP
) {
601 std::swap(LHSR
, RHSR
);
603 if (RHSR
&& RHSR
->getReg() == ARM::SP
) {
606 return CurDAG
->SelectNodeTo(N
, ARM::tADDhirr
, Op
.getValueType(), N0
, N1
);
611 if (Subtarget
->isThumb())
613 if (ConstantSDNode
*C
= dyn_cast
<ConstantSDNode
>(Op
.getOperand(1))) {
614 unsigned RHSV
= C
->getValue();
616 if (isPowerOf2_32(RHSV
-1)) { // 2^n+1?
617 SDOperand V
= Op
.getOperand(0);
619 unsigned ShImm
= ARM_AM::getSORegOpc(ARM_AM::lsl
, Log2_32(RHSV
-1));
620 SDOperand Ops
[] = { V
, V
, CurDAG
->getRegister(0, MVT::i32
),
621 CurDAG
->getTargetConstant(ShImm
, MVT::i32
),
622 getAL(CurDAG
), CurDAG
->getRegister(0, MVT::i32
),
623 CurDAG
->getRegister(0, MVT::i32
) };
624 return CurDAG
->SelectNodeTo(N
, ARM::ADDrs
, MVT::i32
, Ops
, 7);
626 if (isPowerOf2_32(RHSV
+1)) { // 2^n-1?
627 SDOperand V
= Op
.getOperand(0);
629 unsigned ShImm
= ARM_AM::getSORegOpc(ARM_AM::lsl
, Log2_32(RHSV
+1));
630 SDOperand Ops
[] = { V
, V
, CurDAG
->getRegister(0, MVT::i32
),
631 CurDAG
->getTargetConstant(ShImm
, MVT::i32
),
632 getAL(CurDAG
), CurDAG
->getRegister(0, MVT::i32
),
633 CurDAG
->getRegister(0, MVT::i32
) };
634 return CurDAG
->SelectNodeTo(N
, ARM::RSBrs
, MVT::i32
, Ops
, 7);
639 AddToISelQueue(Op
.getOperand(0));
640 return CurDAG
->getTargetNode(ARM::FMRRD
, MVT::i32
, MVT::i32
,
641 Op
.getOperand(0), getAL(CurDAG
),
642 CurDAG
->getRegister(0, MVT::i32
));
643 case ISD::UMUL_LOHI
: {
644 AddToISelQueue(Op
.getOperand(0));
645 AddToISelQueue(Op
.getOperand(1));
646 SDOperand Ops
[] = { Op
.getOperand(0), Op
.getOperand(1),
647 getAL(CurDAG
), CurDAG
->getRegister(0, MVT::i32
),
648 CurDAG
->getRegister(0, MVT::i32
) };
649 return CurDAG
->getTargetNode(ARM::UMULL
, MVT::i32
, MVT::i32
, Ops
, 5);
651 case ISD::SMUL_LOHI
: {
652 AddToISelQueue(Op
.getOperand(0));
653 AddToISelQueue(Op
.getOperand(1));
654 SDOperand Ops
[] = { Op
.getOperand(0), Op
.getOperand(1),
655 getAL(CurDAG
), CurDAG
->getRegister(0, MVT::i32
),
656 CurDAG
->getRegister(0, MVT::i32
) };
657 return CurDAG
->getTargetNode(ARM::SMULL
, MVT::i32
, MVT::i32
, Ops
, 5);
660 LoadSDNode
*LD
= cast
<LoadSDNode
>(Op
);
661 ISD::MemIndexedMode AM
= LD
->getAddressingMode();
662 MVT::ValueType LoadedVT
= LD
->getLoadedVT();
663 if (AM
!= ISD::UNINDEXED
) {
664 SDOperand Offset
, AMOpc
;
665 bool isPre
= (AM
== ISD::PRE_INC
) || (AM
== ISD::PRE_DEC
);
668 if (LoadedVT
== MVT::i32
&&
669 SelectAddrMode2Offset(Op
, LD
->getOffset(), Offset
, AMOpc
)) {
670 Opcode
= isPre
? ARM::LDR_PRE
: ARM::LDR_POST
;
672 } else if (LoadedVT
== MVT::i16
&&
673 SelectAddrMode3Offset(Op
, LD
->getOffset(), Offset
, AMOpc
)) {
675 Opcode
= (LD
->getExtensionType() == ISD::SEXTLOAD
)
676 ? (isPre
? ARM::LDRSH_PRE
: ARM::LDRSH_POST
)
677 : (isPre
? ARM::LDRH_PRE
: ARM::LDRH_POST
);
678 } else if (LoadedVT
== MVT::i8
|| LoadedVT
== MVT::i1
) {
679 if (LD
->getExtensionType() == ISD::SEXTLOAD
) {
680 if (SelectAddrMode3Offset(Op
, LD
->getOffset(), Offset
, AMOpc
)) {
682 Opcode
= isPre
? ARM::LDRSB_PRE
: ARM::LDRSB_POST
;
685 if (SelectAddrMode2Offset(Op
, LD
->getOffset(), Offset
, AMOpc
)) {
687 Opcode
= isPre
? ARM::LDRB_PRE
: ARM::LDRB_POST
;
693 SDOperand Chain
= LD
->getChain();
694 SDOperand Base
= LD
->getBasePtr();
695 AddToISelQueue(Chain
);
696 AddToISelQueue(Base
);
697 AddToISelQueue(Offset
);
698 SDOperand Ops
[]= { Base
, Offset
, AMOpc
, getAL(CurDAG
),
699 CurDAG
->getRegister(0, MVT::i32
), Chain
};
700 return CurDAG
->getTargetNode(Opcode
, MVT::i32
, MVT::i32
,
704 // Other cases are autogenerated.
707 case ARMISD::BRCOND
: {
708 // Pattern: (ARMbrcond:void (bb:Other):$dst, (imm:i32):$cc)
709 // Emits: (Bcc:void (bb:Other):$dst, (imm:i32):$cc)
710 // Pattern complexity = 6 cost = 1 size = 0
712 // Pattern: (ARMbrcond:void (bb:Other):$dst, (imm:i32):$cc)
713 // Emits: (tBcc:void (bb:Other):$dst, (imm:i32):$cc)
714 // Pattern complexity = 6 cost = 1 size = 0
716 unsigned Opc
= Subtarget
->isThumb() ? ARM::tBcc
: ARM::Bcc
;
717 SDOperand Chain
= Op
.getOperand(0);
718 SDOperand N1
= Op
.getOperand(1);
719 SDOperand N2
= Op
.getOperand(2);
720 SDOperand N3
= Op
.getOperand(3);
721 SDOperand InFlag
= Op
.getOperand(4);
722 assert(N1
.getOpcode() == ISD::BasicBlock
);
723 assert(N2
.getOpcode() == ISD::Constant
);
724 assert(N3
.getOpcode() == ISD::Register
);
726 AddToISelQueue(Chain
);
728 AddToISelQueue(InFlag
);
729 SDOperand Tmp2
= CurDAG
->getTargetConstant(((unsigned)
730 cast
<ConstantSDNode
>(N2
)->getValue()), MVT::i32
);
731 SDOperand Ops
[] = { N1
, Tmp2
, N3
, Chain
, InFlag
};
732 SDNode
*ResNode
= CurDAG
->getTargetNode(Opc
, MVT::Other
, MVT::Flag
, Ops
, 5);
733 Chain
= SDOperand(ResNode
, 0);
734 InFlag
= SDOperand(ResNode
, 1);
735 ReplaceUses(SDOperand(Op
.Val
, 1), InFlag
);
736 ReplaceUses(SDOperand(Op
.Val
, 0), SDOperand(Chain
.Val
, Chain
.ResNo
));
740 bool isThumb
= Subtarget
->isThumb();
741 MVT::ValueType VT
= Op
.getValueType();
742 SDOperand N0
= Op
.getOperand(0);
743 SDOperand N1
= Op
.getOperand(1);
744 SDOperand N2
= Op
.getOperand(2);
745 SDOperand N3
= Op
.getOperand(3);
746 SDOperand InFlag
= Op
.getOperand(4);
747 assert(N2
.getOpcode() == ISD::Constant
);
748 assert(N3
.getOpcode() == ISD::Register
);
750 // Pattern: (ARMcmov:i32 GPR:i32:$false, so_reg:i32:$true, (imm:i32):$cc)
751 // Emits: (MOVCCs:i32 GPR:i32:$false, so_reg:i32:$true, (imm:i32):$cc)
752 // Pattern complexity = 18 cost = 1 size = 0
756 if (!isThumb
&& VT
== MVT::i32
&&
757 SelectShifterOperandReg(Op
, N1
, CPTmp0
, CPTmp1
, CPTmp2
)) {
759 AddToISelQueue(CPTmp0
);
760 AddToISelQueue(CPTmp1
);
761 AddToISelQueue(CPTmp2
);
762 AddToISelQueue(InFlag
);
763 SDOperand Tmp2
= CurDAG
->getTargetConstant(((unsigned)
764 cast
<ConstantSDNode
>(N2
)->getValue()), MVT::i32
);
765 SDOperand Ops
[] = { N0
, CPTmp0
, CPTmp1
, CPTmp2
, Tmp2
, N3
, InFlag
};
766 return CurDAG
->SelectNodeTo(Op
.Val
, ARM::MOVCCs
, MVT::i32
, Ops
, 7);
769 // Pattern: (ARMcmov:i32 GPR:i32:$false,
770 // (imm:i32)<<P:Predicate_so_imm>><<X:so_imm_XFORM>>:$true,
772 // Emits: (MOVCCi:i32 GPR:i32:$false,
773 // (so_imm_XFORM:i32 (imm:i32):$true), (imm:i32):$cc)
774 // Pattern complexity = 10 cost = 1 size = 0
775 if (VT
== MVT::i32
&&
776 N3
.getOpcode() == ISD::Constant
&&
777 Predicate_so_imm(N3
.Val
)) {
779 AddToISelQueue(InFlag
);
780 SDOperand Tmp1
= CurDAG
->getTargetConstant(((unsigned)
781 cast
<ConstantSDNode
>(N1
)->getValue()), MVT::i32
);
782 Tmp1
= Transform_so_imm_XFORM(Tmp1
.Val
);
783 SDOperand Tmp2
= CurDAG
->getTargetConstant(((unsigned)
784 cast
<ConstantSDNode
>(N2
)->getValue()), MVT::i32
);
785 SDOperand Ops
[] = { N0
, Tmp1
, Tmp2
, N3
, InFlag
};
786 return CurDAG
->SelectNodeTo(Op
.Val
, ARM::MOVCCi
, MVT::i32
, Ops
, 5);
789 // Pattern: (ARMcmov:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc)
790 // Emits: (MOVCCr:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc)
791 // Pattern complexity = 6 cost = 1 size = 0
793 // Pattern: (ARMcmov:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc)
794 // Emits: (tMOVCCr:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc)
795 // Pattern complexity = 6 cost = 11 size = 0
797 // Also FCPYScc and FCPYDcc.
800 AddToISelQueue(InFlag
);
801 SDOperand Tmp2
= CurDAG
->getTargetConstant(((unsigned)
802 cast
<ConstantSDNode
>(N2
)->getValue()), MVT::i32
);
803 SDOperand Ops
[] = { N0
, N1
, Tmp2
, N3
, InFlag
};
806 default: assert(false && "Illegal conditional move type!");
809 Opc
= isThumb
? ARM::tMOVCCr
: ARM::MOVCCr
;
818 return CurDAG
->SelectNodeTo(Op
.Val
, Opc
, VT
, Ops
, 5);
821 MVT::ValueType VT
= Op
.getValueType();
822 SDOperand N0
= Op
.getOperand(0);
823 SDOperand N1
= Op
.getOperand(1);
824 SDOperand N2
= Op
.getOperand(2);
825 SDOperand N3
= Op
.getOperand(3);
826 SDOperand InFlag
= Op
.getOperand(4);
827 assert(N2
.getOpcode() == ISD::Constant
);
828 assert(N3
.getOpcode() == ISD::Register
);
832 AddToISelQueue(InFlag
);
833 SDOperand Tmp2
= CurDAG
->getTargetConstant(((unsigned)
834 cast
<ConstantSDNode
>(N2
)->getValue()), MVT::i32
);
835 SDOperand Ops
[] = { N0
, N1
, Tmp2
, N3
, InFlag
};
838 default: assert(false && "Illegal conditional move type!");
847 return CurDAG
->SelectNodeTo(Op
.Val
, Opc
, VT
, Ops
, 5);
850 return SelectCode(Op
);
853 /// createARMISelDag - This pass converts a legalized DAG into a
854 /// ARM-specific DAG, ready for instruction scheduling.
856 FunctionPass
*llvm::createARMISelDag(ARMTargetMachine
&TM
) {
857 return new ARMDAGToDAGISel(TM
);