1 //===-- ARMISelDAGToDAG.cpp - A dag to dag inst selector for ARM ----------===//
3 // The LLVM Compiler Infrastructure
5 // This file was developed by Chris Lattner and is distributed under
6 // the University of Illinois Open Source 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/CodeGen/SSARegMap.h"
29 #include "llvm/Target/TargetLowering.h"
30 #include "llvm/Target/TargetOptions.h"
31 #include "llvm/Support/Debug.h"
34 //===--------------------------------------------------------------------===//
35 /// ARMDAGToDAGISel - ARM specific code to select ARM machine
36 /// instructions for SelectionDAG operations.
39 class ARMDAGToDAGISel
: public SelectionDAGISel
{
40 ARMTargetLowering Lowering
;
42 /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
43 /// make the right decision when generating code for different targets.
44 const ARMSubtarget
*Subtarget
;
47 ARMDAGToDAGISel(ARMTargetMachine
&TM
)
48 : SelectionDAGISel(Lowering
), Lowering(TM
),
49 Subtarget(&TM
.getSubtarget
<ARMSubtarget
>()) {
52 virtual const char *getPassName() const {
53 return "ARM Instruction Selection";
56 SDNode
*Select(SDOperand Op
);
57 virtual void InstructionSelectBasicBlock(SelectionDAG
&DAG
);
58 bool SelectAddrMode2(SDOperand Op
, SDOperand N
, SDOperand
&Base
,
59 SDOperand
&Offset
, SDOperand
&Opc
);
60 bool SelectAddrMode2Offset(SDOperand Op
, SDOperand N
,
61 SDOperand
&Offset
, SDOperand
&Opc
);
62 bool SelectAddrMode3(SDOperand Op
, SDOperand N
, SDOperand
&Base
,
63 SDOperand
&Offset
, SDOperand
&Opc
);
64 bool SelectAddrMode3Offset(SDOperand Op
, SDOperand N
,
65 SDOperand
&Offset
, SDOperand
&Opc
);
66 bool SelectAddrMode5(SDOperand Op
, SDOperand N
, SDOperand
&Base
,
69 bool SelectAddrModePC(SDOperand Op
, SDOperand N
, SDOperand
&Offset
,
72 bool SelectThumbAddrModeRR(SDOperand Op
, SDOperand N
, SDOperand
&Base
,
74 bool SelectThumbAddrModeRI5(SDOperand Op
, SDOperand N
, unsigned Scale
,
75 SDOperand
&Base
, SDOperand
&OffImm
,
77 bool SelectThumbAddrModeS1(SDOperand Op
, SDOperand N
, SDOperand
&Base
,
78 SDOperand
&OffImm
, SDOperand
&Offset
);
79 bool SelectThumbAddrModeS2(SDOperand Op
, SDOperand N
, SDOperand
&Base
,
80 SDOperand
&OffImm
, SDOperand
&Offset
);
81 bool SelectThumbAddrModeS4(SDOperand Op
, SDOperand N
, SDOperand
&Base
,
82 SDOperand
&OffImm
, SDOperand
&Offset
);
83 bool SelectThumbAddrModeSP(SDOperand Op
, SDOperand N
, SDOperand
&Base
,
86 bool SelectShifterOperandReg(SDOperand Op
, SDOperand N
, SDOperand
&A
,
87 SDOperand
&B
, SDOperand
&C
);
89 // Include the pieces autogenerated from the target description.
90 #include "ARMGenDAGISel.inc"
94 void ARMDAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG
&DAG
) {
97 DAG
.setRoot(SelectRoot(DAG
.getRoot()));
98 DAG
.RemoveDeadNodes();
100 ScheduleAndEmitDAG(DAG
);
103 bool ARMDAGToDAGISel::SelectAddrMode2(SDOperand Op
, SDOperand N
,
104 SDOperand
&Base
, SDOperand
&Offset
,
106 if (N
.getOpcode() == ISD::MUL
) {
107 if (ConstantSDNode
*RHS
= dyn_cast
<ConstantSDNode
>(N
.getOperand(1))) {
108 // X * [3,5,9] -> X + X * [2,4,8] etc.
109 int RHSC
= (int)RHS
->getValue();
112 ARM_AM::AddrOpc AddSub
= ARM_AM::add
;
114 AddSub
= ARM_AM::sub
;
117 if (isPowerOf2_32(RHSC
)) {
118 unsigned ShAmt
= Log2_32(RHSC
);
119 Base
= Offset
= N
.getOperand(0);
120 Opc
= CurDAG
->getTargetConstant(ARM_AM::getAM2Opc(AddSub
, ShAmt
,
129 if (N
.getOpcode() != ISD::ADD
&& N
.getOpcode() != ISD::SUB
) {
131 if (N
.getOpcode() == ISD::FrameIndex
) {
132 int FI
= cast
<FrameIndexSDNode
>(N
)->getIndex();
133 Base
= CurDAG
->getTargetFrameIndex(FI
, TLI
.getPointerTy());
134 } else if (N
.getOpcode() == ARMISD::Wrapper
) {
135 Base
= N
.getOperand(0);
137 Offset
= CurDAG
->getRegister(0, MVT::i32
);
138 Opc
= CurDAG
->getTargetConstant(ARM_AM::getAM2Opc(ARM_AM::add
, 0,
144 // Match simple R +/- imm12 operands.
145 if (N
.getOpcode() == ISD::ADD
)
146 if (ConstantSDNode
*RHS
= dyn_cast
<ConstantSDNode
>(N
.getOperand(1))) {
147 int RHSC
= (int)RHS
->getValue();
148 if ((RHSC
>= 0 && RHSC
< 0x1000) ||
149 (RHSC
< 0 && RHSC
> -0x1000)) { // 12 bits.
150 Base
= N
.getOperand(0);
151 if (Base
.getOpcode() == ISD::FrameIndex
) {
152 int FI
= cast
<FrameIndexSDNode
>(Base
)->getIndex();
153 Base
= CurDAG
->getTargetFrameIndex(FI
, TLI
.getPointerTy());
155 Offset
= CurDAG
->getRegister(0, MVT::i32
);
157 ARM_AM::AddrOpc AddSub
= ARM_AM::add
;
159 AddSub
= ARM_AM::sub
;
162 Opc
= CurDAG
->getTargetConstant(ARM_AM::getAM2Opc(AddSub
, RHSC
,
169 // Otherwise this is R +/- [possibly shifted] R
170 ARM_AM::AddrOpc AddSub
= N
.getOpcode() == ISD::ADD
? ARM_AM::add
:ARM_AM::sub
;
171 ARM_AM::ShiftOpc ShOpcVal
= ARM_AM::getShiftOpcForNode(N
.getOperand(1));
174 Base
= N
.getOperand(0);
175 Offset
= N
.getOperand(1);
177 if (ShOpcVal
!= ARM_AM::no_shift
) {
178 // Check to see if the RHS of the shift is a constant, if not, we can't fold
180 if (ConstantSDNode
*Sh
=
181 dyn_cast
<ConstantSDNode
>(N
.getOperand(1).getOperand(1))) {
182 ShAmt
= Sh
->getValue();
183 Offset
= N
.getOperand(1).getOperand(0);
185 ShOpcVal
= ARM_AM::no_shift
;
189 // Try matching (R shl C) + (R).
190 if (N
.getOpcode() == ISD::ADD
&& ShOpcVal
== ARM_AM::no_shift
) {
191 ShOpcVal
= ARM_AM::getShiftOpcForNode(N
.getOperand(0));
192 if (ShOpcVal
!= ARM_AM::no_shift
) {
193 // Check to see if the RHS of the shift is a constant, if not, we can't
195 if (ConstantSDNode
*Sh
=
196 dyn_cast
<ConstantSDNode
>(N
.getOperand(0).getOperand(1))) {
197 ShAmt
= Sh
->getValue();
198 Offset
= N
.getOperand(0).getOperand(0);
199 Base
= N
.getOperand(1);
201 ShOpcVal
= ARM_AM::no_shift
;
206 Opc
= CurDAG
->getTargetConstant(ARM_AM::getAM2Opc(AddSub
, ShAmt
, ShOpcVal
),
211 bool ARMDAGToDAGISel::SelectAddrMode2Offset(SDOperand Op
, SDOperand N
,
212 SDOperand
&Offset
, SDOperand
&Opc
) {
213 unsigned Opcode
= Op
.getOpcode();
214 ISD::MemIndexedMode AM
= (Opcode
== ISD::LOAD
)
215 ? cast
<LoadSDNode
>(Op
)->getAddressingMode()
216 : cast
<StoreSDNode
>(Op
)->getAddressingMode();
217 ARM_AM::AddrOpc AddSub
= (AM
== ISD::PRE_INC
|| AM
== ISD::POST_INC
)
218 ? ARM_AM::add
: ARM_AM::sub
;
219 if (ConstantSDNode
*C
= dyn_cast
<ConstantSDNode
>(N
)) {
220 int Val
= (int)C
->getValue();
221 if (Val
>= 0 && Val
< 0x1000) { // 12 bits.
222 Offset
= CurDAG
->getRegister(0, MVT::i32
);
223 Opc
= CurDAG
->getTargetConstant(ARM_AM::getAM2Opc(AddSub
, Val
,
231 ARM_AM::ShiftOpc ShOpcVal
= ARM_AM::getShiftOpcForNode(N
);
233 if (ShOpcVal
!= ARM_AM::no_shift
) {
234 // Check to see if the RHS of the shift is a constant, if not, we can't fold
236 if (ConstantSDNode
*Sh
= dyn_cast
<ConstantSDNode
>(N
.getOperand(1))) {
237 ShAmt
= Sh
->getValue();
238 Offset
= N
.getOperand(0);
240 ShOpcVal
= ARM_AM::no_shift
;
244 Opc
= CurDAG
->getTargetConstant(ARM_AM::getAM2Opc(AddSub
, ShAmt
, ShOpcVal
),
250 bool ARMDAGToDAGISel::SelectAddrMode3(SDOperand Op
, SDOperand N
,
251 SDOperand
&Base
, SDOperand
&Offset
,
253 if (N
.getOpcode() == ISD::SUB
) {
254 // X - C is canonicalize to X + -C, no need to handle it here.
255 Base
= N
.getOperand(0);
256 Offset
= N
.getOperand(1);
257 Opc
= CurDAG
->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::sub
, 0),MVT::i32
);
261 if (N
.getOpcode() != ISD::ADD
) {
263 if (N
.getOpcode() == ISD::FrameIndex
) {
264 int FI
= cast
<FrameIndexSDNode
>(N
)->getIndex();
265 Base
= CurDAG
->getTargetFrameIndex(FI
, TLI
.getPointerTy());
267 Offset
= CurDAG
->getRegister(0, MVT::i32
);
268 Opc
= CurDAG
->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::add
, 0),MVT::i32
);
272 // If the RHS is +/- imm8, fold into addr mode.
273 if (ConstantSDNode
*RHS
= dyn_cast
<ConstantSDNode
>(N
.getOperand(1))) {
274 int RHSC
= (int)RHS
->getValue();
275 if ((RHSC
>= 0 && RHSC
< 256) ||
276 (RHSC
< 0 && RHSC
> -256)) { // note -256 itself isn't allowed.
277 Base
= N
.getOperand(0);
278 if (Base
.getOpcode() == ISD::FrameIndex
) {
279 int FI
= cast
<FrameIndexSDNode
>(Base
)->getIndex();
280 Base
= CurDAG
->getTargetFrameIndex(FI
, TLI
.getPointerTy());
282 Offset
= CurDAG
->getRegister(0, MVT::i32
);
284 ARM_AM::AddrOpc AddSub
= ARM_AM::add
;
286 AddSub
= ARM_AM::sub
;
289 Opc
= CurDAG
->getTargetConstant(ARM_AM::getAM3Opc(AddSub
, RHSC
),MVT::i32
);
294 Base
= N
.getOperand(0);
295 Offset
= N
.getOperand(1);
296 Opc
= CurDAG
->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::add
, 0), MVT::i32
);
300 bool ARMDAGToDAGISel::SelectAddrMode3Offset(SDOperand Op
, SDOperand N
,
301 SDOperand
&Offset
, SDOperand
&Opc
) {
302 unsigned Opcode
= Op
.getOpcode();
303 ISD::MemIndexedMode AM
= (Opcode
== ISD::LOAD
)
304 ? cast
<LoadSDNode
>(Op
)->getAddressingMode()
305 : cast
<StoreSDNode
>(Op
)->getAddressingMode();
306 ARM_AM::AddrOpc AddSub
= (AM
== ISD::PRE_INC
|| AM
== ISD::POST_INC
)
307 ? ARM_AM::add
: ARM_AM::sub
;
308 if (ConstantSDNode
*C
= dyn_cast
<ConstantSDNode
>(N
)) {
309 int Val
= (int)C
->getValue();
310 if (Val
>= 0 && Val
< 256) {
311 Offset
= CurDAG
->getRegister(0, MVT::i32
);
312 Opc
= CurDAG
->getTargetConstant(ARM_AM::getAM3Opc(AddSub
, Val
), MVT::i32
);
318 Opc
= CurDAG
->getTargetConstant(ARM_AM::getAM3Opc(AddSub
, 0), MVT::i32
);
323 bool ARMDAGToDAGISel::SelectAddrMode5(SDOperand Op
, SDOperand N
,
324 SDOperand
&Base
, SDOperand
&Offset
) {
325 if (N
.getOpcode() != ISD::ADD
) {
327 if (N
.getOpcode() == ISD::FrameIndex
) {
328 int FI
= cast
<FrameIndexSDNode
>(N
)->getIndex();
329 Base
= CurDAG
->getTargetFrameIndex(FI
, TLI
.getPointerTy());
330 } else if (N
.getOpcode() == ARMISD::Wrapper
) {
331 Base
= N
.getOperand(0);
333 Offset
= CurDAG
->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::add
, 0),
338 // If the RHS is +/- imm8, fold into addr mode.
339 if (ConstantSDNode
*RHS
= dyn_cast
<ConstantSDNode
>(N
.getOperand(1))) {
340 int RHSC
= (int)RHS
->getValue();
341 if ((RHSC
& 3) == 0) { // The constant is implicitly multiplied by 4.
343 if ((RHSC
>= 0 && RHSC
< 256) ||
344 (RHSC
< 0 && RHSC
> -256)) { // note -256 itself isn't allowed.
345 Base
= N
.getOperand(0);
346 if (Base
.getOpcode() == ISD::FrameIndex
) {
347 int FI
= cast
<FrameIndexSDNode
>(Base
)->getIndex();
348 Base
= CurDAG
->getTargetFrameIndex(FI
, TLI
.getPointerTy());
351 ARM_AM::AddrOpc AddSub
= ARM_AM::add
;
353 AddSub
= ARM_AM::sub
;
356 Offset
= CurDAG
->getTargetConstant(ARM_AM::getAM5Opc(AddSub
, RHSC
),
364 Offset
= CurDAG
->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::add
, 0),
369 bool ARMDAGToDAGISel::SelectAddrModePC(SDOperand Op
, SDOperand N
,
370 SDOperand
&Offset
, SDOperand
&Label
) {
371 if (N
.getOpcode() == ARMISD::PIC_ADD
&& N
.hasOneUse()) {
372 Offset
= N
.getOperand(0);
373 SDOperand N1
= N
.getOperand(1);
374 Label
= CurDAG
->getTargetConstant(cast
<ConstantSDNode
>(N1
)->getValue(),
381 bool ARMDAGToDAGISel::SelectThumbAddrModeRR(SDOperand Op
, SDOperand N
,
382 SDOperand
&Base
, SDOperand
&Offset
){
383 if (N
.getOpcode() != ISD::ADD
) {
385 // We must materialize a zero in a reg! Returning an constant here won't
386 // work since its node is -1 so it won't get added to the selection queue.
387 // Explicitly issue a tMOVri8 node!
388 Offset
= SDOperand(CurDAG
->getTargetNode(ARM::tMOVi8
, MVT::i32
,
389 CurDAG
->getTargetConstant(0, MVT::i32
)), 0);
393 Base
= N
.getOperand(0);
394 Offset
= N
.getOperand(1);
399 ARMDAGToDAGISel::SelectThumbAddrModeRI5(SDOperand Op
, SDOperand N
,
400 unsigned Scale
, SDOperand
&Base
,
401 SDOperand
&OffImm
, SDOperand
&Offset
) {
403 SDOperand TmpBase
, TmpOffImm
;
404 if (SelectThumbAddrModeSP(Op
, N
, TmpBase
, TmpOffImm
))
405 return false; // We want to select tLDRspi / tSTRspi instead.
406 if (N
.getOpcode() == ARMISD::Wrapper
&&
407 N
.getOperand(0).getOpcode() == ISD::TargetConstantPool
)
408 return false; // We want to select tLDRpci instead.
411 if (N
.getOpcode() != ISD::ADD
) {
412 Base
= (N
.getOpcode() == ARMISD::Wrapper
) ? N
.getOperand(0) : N
;
413 Offset
= CurDAG
->getRegister(0, MVT::i32
);
414 OffImm
= CurDAG
->getTargetConstant(0, MVT::i32
);
418 // Thumb does not have [sp, r] address mode.
419 RegisterSDNode
*LHSR
= dyn_cast
<RegisterSDNode
>(N
.getOperand(0));
420 RegisterSDNode
*RHSR
= dyn_cast
<RegisterSDNode
>(N
.getOperand(1));
421 if ((LHSR
&& LHSR
->getReg() == ARM::SP
) ||
422 (RHSR
&& RHSR
->getReg() == ARM::SP
)) {
424 Offset
= CurDAG
->getRegister(0, MVT::i32
);
425 OffImm
= CurDAG
->getTargetConstant(0, MVT::i32
);
429 // If the RHS is + imm5 * scale, fold into addr mode.
430 if (ConstantSDNode
*RHS
= dyn_cast
<ConstantSDNode
>(N
.getOperand(1))) {
431 int RHSC
= (int)RHS
->getValue();
432 if ((RHSC
& (Scale
-1)) == 0) { // The constant is implicitly multiplied.
434 if (RHSC
>= 0 && RHSC
< 32) {
435 Base
= N
.getOperand(0);
436 Offset
= CurDAG
->getRegister(0, MVT::i32
);
437 OffImm
= CurDAG
->getTargetConstant(RHSC
, MVT::i32
);
443 Base
= N
.getOperand(0);
444 Offset
= N
.getOperand(1);
445 OffImm
= CurDAG
->getTargetConstant(0, MVT::i32
);
449 bool ARMDAGToDAGISel::SelectThumbAddrModeS1(SDOperand Op
, SDOperand N
,
450 SDOperand
&Base
, SDOperand
&OffImm
,
452 return SelectThumbAddrModeRI5(Op
, N
, 1, Base
, OffImm
, Offset
);
455 bool ARMDAGToDAGISel::SelectThumbAddrModeS2(SDOperand Op
, SDOperand N
,
456 SDOperand
&Base
, SDOperand
&OffImm
,
458 return SelectThumbAddrModeRI5(Op
, N
, 2, Base
, OffImm
, Offset
);
461 bool ARMDAGToDAGISel::SelectThumbAddrModeS4(SDOperand Op
, SDOperand N
,
462 SDOperand
&Base
, SDOperand
&OffImm
,
464 return SelectThumbAddrModeRI5(Op
, N
, 4, Base
, OffImm
, Offset
);
467 bool ARMDAGToDAGISel::SelectThumbAddrModeSP(SDOperand Op
, SDOperand N
,
468 SDOperand
&Base
, SDOperand
&OffImm
) {
469 if (N
.getOpcode() == ISD::FrameIndex
) {
470 int FI
= cast
<FrameIndexSDNode
>(N
)->getIndex();
471 Base
= CurDAG
->getTargetFrameIndex(FI
, TLI
.getPointerTy());
472 OffImm
= CurDAG
->getTargetConstant(0, MVT::i32
);
476 if (N
.getOpcode() != ISD::ADD
)
479 RegisterSDNode
*LHSR
= dyn_cast
<RegisterSDNode
>(N
.getOperand(0));
480 if (N
.getOperand(0).getOpcode() == ISD::FrameIndex
||
481 (LHSR
&& LHSR
->getReg() == ARM::SP
)) {
482 // If the RHS is + imm8 * scale, fold into addr mode.
483 if (ConstantSDNode
*RHS
= dyn_cast
<ConstantSDNode
>(N
.getOperand(1))) {
484 int RHSC
= (int)RHS
->getValue();
485 if ((RHSC
& 3) == 0) { // The constant is implicitly multiplied.
487 if (RHSC
>= 0 && RHSC
< 256) {
488 Base
= N
.getOperand(0);
489 if (Base
.getOpcode() == ISD::FrameIndex
) {
490 int FI
= cast
<FrameIndexSDNode
>(Base
)->getIndex();
491 Base
= CurDAG
->getTargetFrameIndex(FI
, TLI
.getPointerTy());
493 OffImm
= CurDAG
->getTargetConstant(RHSC
, MVT::i32
);
503 bool ARMDAGToDAGISel::SelectShifterOperandReg(SDOperand Op
,
508 ARM_AM::ShiftOpc ShOpcVal
= ARM_AM::getShiftOpcForNode(N
);
510 // Don't match base register only case. That is matched to a separate
511 // lower complexity pattern with explicit register operand.
512 if (ShOpcVal
== ARM_AM::no_shift
) return false;
514 BaseReg
= N
.getOperand(0);
515 unsigned ShImmVal
= 0;
516 if (ConstantSDNode
*RHS
= dyn_cast
<ConstantSDNode
>(N
.getOperand(1))) {
517 ShReg
= CurDAG
->getRegister(0, MVT::i32
);
518 ShImmVal
= RHS
->getValue() & 31;
520 ShReg
= N
.getOperand(1);
522 Opc
= CurDAG
->getTargetConstant(ARM_AM::getSORegOpc(ShOpcVal
, ShImmVal
),
527 /// getAL - Returns a ARMCC::AL immediate node.
528 static inline SDOperand
getAL(SelectionDAG
*CurDAG
) {
529 return CurDAG
->getTargetConstant((uint64_t)ARMCC::AL
, MVT::i32
);
533 SDNode
*ARMDAGToDAGISel::Select(SDOperand Op
) {
535 unsigned Opcode
= N
->getOpcode();
537 if (Opcode
>= ISD::BUILTIN_OP_END
&& Opcode
< ARMISD::FIRST_NUMBER
)
538 return NULL
; // Already selected.
540 switch (N
->getOpcode()) {
542 case ISD::Constant
: {
543 unsigned Val
= cast
<ConstantSDNode
>(N
)->getValue();
545 if (Subtarget
->isThumb())
546 UseCP
= (Val
> 255 && // MOV
547 ~Val
> 255 && // MOV + MVN
548 !ARM_AM::isThumbImmShiftedVal(Val
)); // MOV + LSL
550 UseCP
= (ARM_AM::getSOImmVal(Val
) == -1 && // MOV
551 ARM_AM::getSOImmVal(~Val
) == -1 && // MVN
552 !ARM_AM::isSOImmTwoPartVal(Val
)); // two instrs.
555 CurDAG
->getTargetConstantPool(ConstantInt::get(Type::Int32Ty
, Val
),
559 if (Subtarget
->isThumb())
560 ResNode
= CurDAG
->getTargetNode(ARM::tLDRcp
, MVT::i32
, MVT::Other
,
561 CPIdx
, CurDAG
->getEntryNode());
565 CurDAG
->getRegister(0, MVT::i32
),
566 CurDAG
->getTargetConstant(0, MVT::i32
),
568 CurDAG
->getRegister(0, MVT::i32
),
569 CurDAG
->getEntryNode()
571 ResNode
=CurDAG
->getTargetNode(ARM::LDRcp
, MVT::i32
, MVT::Other
, Ops
, 6);
573 ReplaceUses(Op
, SDOperand(ResNode
, 0));
577 // Other cases are autogenerated.
580 case ISD::FrameIndex
: {
581 // Selects to ADDri FI, 0 which in turn will become ADDri SP, imm.
582 int FI
= cast
<FrameIndexSDNode
>(N
)->getIndex();
583 SDOperand TFI
= CurDAG
->getTargetFrameIndex(FI
, TLI
.getPointerTy());
584 if (Subtarget
->isThumb())
585 return CurDAG
->SelectNodeTo(N
, ARM::tADDrSPi
, MVT::i32
, TFI
,
586 CurDAG
->getTargetConstant(0, MVT::i32
));
588 SDOperand Ops
[] = { TFI
, CurDAG
->getTargetConstant(0, MVT::i32
),
589 getAL(CurDAG
), CurDAG
->getRegister(0, MVT::i32
),
590 CurDAG
->getRegister(0, MVT::i32
) };
591 return CurDAG
->SelectNodeTo(N
, ARM::ADDri
, MVT::i32
, Ops
, 5);
595 // Select add sp, c to tADDhirr.
596 SDOperand N0
= Op
.getOperand(0);
597 SDOperand N1
= Op
.getOperand(1);
598 RegisterSDNode
*LHSR
= dyn_cast
<RegisterSDNode
>(Op
.getOperand(0));
599 RegisterSDNode
*RHSR
= dyn_cast
<RegisterSDNode
>(Op
.getOperand(1));
600 if (LHSR
&& LHSR
->getReg() == ARM::SP
) {
602 std::swap(LHSR
, RHSR
);
604 if (RHSR
&& RHSR
->getReg() == ARM::SP
) {
607 return CurDAG
->SelectNodeTo(N
, ARM::tADDhirr
, Op
.getValueType(), N0
, N1
);
612 if (Subtarget
->isThumb())
614 if (ConstantSDNode
*C
= dyn_cast
<ConstantSDNode
>(Op
.getOperand(1))) {
615 unsigned RHSV
= C
->getValue();
617 if (isPowerOf2_32(RHSV
-1)) { // 2^n+1?
618 SDOperand V
= Op
.getOperand(0);
620 unsigned ShImm
= ARM_AM::getSORegOpc(ARM_AM::lsl
, Log2_32(RHSV
-1));
621 SDOperand Ops
[] = { V
, V
, CurDAG
->getRegister(0, MVT::i32
),
622 CurDAG
->getTargetConstant(ShImm
, MVT::i32
),
623 getAL(CurDAG
), CurDAG
->getRegister(0, MVT::i32
),
624 CurDAG
->getRegister(0, MVT::i32
) };
625 return CurDAG
->SelectNodeTo(N
, ARM::ADDrs
, MVT::i32
, Ops
, 7);
627 if (isPowerOf2_32(RHSV
+1)) { // 2^n-1?
628 SDOperand V
= Op
.getOperand(0);
630 unsigned ShImm
= ARM_AM::getSORegOpc(ARM_AM::lsl
, Log2_32(RHSV
+1));
631 SDOperand Ops
[] = { V
, V
, CurDAG
->getRegister(0, MVT::i32
),
632 CurDAG
->getTargetConstant(ShImm
, MVT::i32
),
633 getAL(CurDAG
), CurDAG
->getRegister(0, MVT::i32
),
634 CurDAG
->getRegister(0, MVT::i32
) };
635 return CurDAG
->SelectNodeTo(N
, ARM::RSBrs
, MVT::i32
, Ops
, 7);
640 AddToISelQueue(Op
.getOperand(0));
641 return CurDAG
->getTargetNode(ARM::FMRRD
, MVT::i32
, MVT::i32
,
642 Op
.getOperand(0), getAL(CurDAG
),
643 CurDAG
->getRegister(0, MVT::i32
));
644 case ARMISD::MULHILOU
: {
645 AddToISelQueue(Op
.getOperand(0));
646 AddToISelQueue(Op
.getOperand(1));
647 SDOperand Ops
[] = { Op
.getOperand(0), Op
.getOperand(1),
648 getAL(CurDAG
), CurDAG
->getRegister(0, MVT::i32
),
649 CurDAG
->getRegister(0, MVT::i32
) };
650 return CurDAG
->getTargetNode(ARM::UMULL
, MVT::i32
, MVT::i32
, Ops
, 5);
652 case ARMISD::MULHILOS
: {
653 AddToISelQueue(Op
.getOperand(0));
654 AddToISelQueue(Op
.getOperand(1));
655 SDOperand Ops
[] = { Op
.getOperand(0), Op
.getOperand(1),
656 getAL(CurDAG
), CurDAG
->getRegister(0, MVT::i32
),
657 CurDAG
->getRegister(0, MVT::i32
) };
658 return CurDAG
->getTargetNode(ARM::SMULL
, MVT::i32
, MVT::i32
, Ops
, 5);
661 LoadSDNode
*LD
= cast
<LoadSDNode
>(Op
);
662 ISD::MemIndexedMode AM
= LD
->getAddressingMode();
663 MVT::ValueType LoadedVT
= LD
->getLoadedVT();
664 if (AM
!= ISD::UNINDEXED
) {
665 SDOperand Offset
, AMOpc
;
666 bool isPre
= (AM
== ISD::PRE_INC
) || (AM
== ISD::PRE_DEC
);
669 if (LoadedVT
== MVT::i32
&&
670 SelectAddrMode2Offset(Op
, LD
->getOffset(), Offset
, AMOpc
)) {
671 Opcode
= isPre
? ARM::LDR_PRE
: ARM::LDR_POST
;
673 } else if (LoadedVT
== MVT::i16
&&
674 SelectAddrMode3Offset(Op
, LD
->getOffset(), Offset
, AMOpc
)) {
676 Opcode
= (LD
->getExtensionType() == ISD::SEXTLOAD
)
677 ? (isPre
? ARM::LDRSH_PRE
: ARM::LDRSH_POST
)
678 : (isPre
? ARM::LDRH_PRE
: ARM::LDRH_POST
);
679 } else if (LoadedVT
== MVT::i8
|| LoadedVT
== MVT::i1
) {
680 if (LD
->getExtensionType() == ISD::SEXTLOAD
) {
681 if (SelectAddrMode3Offset(Op
, LD
->getOffset(), Offset
, AMOpc
)) {
683 Opcode
= isPre
? ARM::LDRSB_PRE
: ARM::LDRSB_POST
;
686 if (SelectAddrMode2Offset(Op
, LD
->getOffset(), Offset
, AMOpc
)) {
688 Opcode
= isPre
? ARM::LDRB_PRE
: ARM::LDRB_POST
;
694 SDOperand Chain
= LD
->getChain();
695 SDOperand Base
= LD
->getBasePtr();
696 AddToISelQueue(Chain
);
697 AddToISelQueue(Base
);
698 AddToISelQueue(Offset
);
699 SDOperand Ops
[]= { Base
, Offset
, AMOpc
, getAL(CurDAG
),
700 CurDAG
->getRegister(0, MVT::i32
), Chain
};
701 return CurDAG
->getTargetNode(Opcode
, MVT::i32
, MVT::i32
,
705 // Other cases are autogenerated.
708 case ARMISD::BRCOND
: {
709 // Pattern: (ARMbrcond:void (bb:Other):$dst, (imm:i32):$cc)
710 // Emits: (Bcc:void (bb:Other):$dst, (imm:i32):$cc)
711 // Pattern complexity = 6 cost = 1 size = 0
713 // Pattern: (ARMbrcond:void (bb:Other):$dst, (imm:i32):$cc)
714 // Emits: (tBcc:void (bb:Other):$dst, (imm:i32):$cc)
715 // Pattern complexity = 6 cost = 1 size = 0
717 unsigned Opc
= Subtarget
->isThumb() ? ARM::tBcc
: ARM::Bcc
;
718 SDOperand Chain
= Op
.getOperand(0);
719 SDOperand N1
= Op
.getOperand(1);
720 SDOperand N2
= Op
.getOperand(2);
721 SDOperand N3
= Op
.getOperand(3);
722 SDOperand InFlag
= Op
.getOperand(4);
723 assert(N1
.getOpcode() == ISD::BasicBlock
);
724 assert(N2
.getOpcode() == ISD::Constant
);
725 assert(N3
.getOpcode() == ISD::Register
);
727 AddToISelQueue(Chain
);
729 AddToISelQueue(InFlag
);
730 SDOperand Tmp2
= CurDAG
->getTargetConstant(((unsigned)
731 cast
<ConstantSDNode
>(N2
)->getValue()), MVT::i32
);
732 SDOperand Ops
[] = { N1
, Tmp2
, N3
, Chain
, InFlag
};
733 SDNode
*ResNode
= CurDAG
->getTargetNode(Opc
, MVT::Other
, MVT::Flag
, Ops
, 5);
734 Chain
= SDOperand(ResNode
, 0);
735 InFlag
= SDOperand(ResNode
, 1);
736 ReplaceUses(SDOperand(Op
.Val
, 1), InFlag
);
737 ReplaceUses(SDOperand(Op
.Val
, 0), SDOperand(Chain
.Val
, Chain
.ResNo
));
741 bool isThumb
= Subtarget
->isThumb();
742 MVT::ValueType VT
= Op
.getValueType();
743 SDOperand N0
= Op
.getOperand(0);
744 SDOperand N1
= Op
.getOperand(1);
745 SDOperand N2
= Op
.getOperand(2);
746 SDOperand N3
= Op
.getOperand(3);
747 SDOperand InFlag
= Op
.getOperand(4);
748 assert(N2
.getOpcode() == ISD::Constant
);
749 assert(N3
.getOpcode() == ISD::Register
);
751 // Pattern: (ARMcmov:i32 GPR:i32:$false, so_reg:i32:$true, (imm:i32):$cc)
752 // Emits: (MOVCCs:i32 GPR:i32:$false, so_reg:i32:$true, (imm:i32):$cc)
753 // Pattern complexity = 18 cost = 1 size = 0
757 if (!isThumb
&& VT
== MVT::i32
&&
758 SelectShifterOperandReg(Op
, N1
, CPTmp0
, CPTmp1
, CPTmp2
)) {
760 AddToISelQueue(CPTmp0
);
761 AddToISelQueue(CPTmp1
);
762 AddToISelQueue(CPTmp2
);
763 AddToISelQueue(InFlag
);
764 SDOperand Tmp2
= CurDAG
->getTargetConstant(((unsigned)
765 cast
<ConstantSDNode
>(N2
)->getValue()), MVT::i32
);
766 SDOperand Ops
[] = { N0
, CPTmp0
, CPTmp1
, CPTmp2
, Tmp2
, N3
, InFlag
};
767 return CurDAG
->SelectNodeTo(Op
.Val
, ARM::MOVCCs
, MVT::i32
, Ops
, 7);
770 // Pattern: (ARMcmov:i32 GPR:i32:$false,
771 // (imm:i32)<<P:Predicate_so_imm>><<X:so_imm_XFORM>>:$true,
773 // Emits: (MOVCCi:i32 GPR:i32:$false,
774 // (so_imm_XFORM:i32 (imm:i32):$true), (imm:i32):$cc)
775 // Pattern complexity = 10 cost = 1 size = 0
776 if (VT
== MVT::i32
&&
777 N3
.getOpcode() == ISD::Constant
&&
778 Predicate_so_imm(N3
.Val
)) {
780 AddToISelQueue(InFlag
);
781 SDOperand Tmp1
= CurDAG
->getTargetConstant(((unsigned)
782 cast
<ConstantSDNode
>(N1
)->getValue()), MVT::i32
);
783 Tmp1
= Transform_so_imm_XFORM(Tmp1
.Val
);
784 SDOperand Tmp2
= CurDAG
->getTargetConstant(((unsigned)
785 cast
<ConstantSDNode
>(N2
)->getValue()), MVT::i32
);
786 SDOperand Ops
[] = { N0
, Tmp1
, Tmp2
, N3
, InFlag
};
787 return CurDAG
->SelectNodeTo(Op
.Val
, ARM::MOVCCi
, MVT::i32
, Ops
, 5);
790 // Pattern: (ARMcmov:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc)
791 // Emits: (MOVCCr:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc)
792 // Pattern complexity = 6 cost = 1 size = 0
794 // Pattern: (ARMcmov:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc)
795 // Emits: (tMOVCCr:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc)
796 // Pattern complexity = 6 cost = 11 size = 0
798 // Also FCPYScc and FCPYDcc.
801 AddToISelQueue(InFlag
);
802 SDOperand Tmp2
= CurDAG
->getTargetConstant(((unsigned)
803 cast
<ConstantSDNode
>(N2
)->getValue()), MVT::i32
);
804 SDOperand Ops
[] = { N0
, N1
, Tmp2
, N3
, InFlag
};
807 default: assert(false && "Illegal conditional move type!");
810 Opc
= isThumb
? ARM::tMOVCCr
: ARM::MOVCCr
;
819 return CurDAG
->SelectNodeTo(Op
.Val
, Opc
, VT
, Ops
, 5);
822 MVT::ValueType VT
= Op
.getValueType();
823 SDOperand N0
= Op
.getOperand(0);
824 SDOperand N1
= Op
.getOperand(1);
825 SDOperand N2
= Op
.getOperand(2);
826 SDOperand N3
= Op
.getOperand(3);
827 SDOperand InFlag
= Op
.getOperand(4);
828 assert(N2
.getOpcode() == ISD::Constant
);
829 assert(N3
.getOpcode() == ISD::Register
);
833 AddToISelQueue(InFlag
);
834 SDOperand Tmp2
= CurDAG
->getTargetConstant(((unsigned)
835 cast
<ConstantSDNode
>(N2
)->getValue()), MVT::i32
);
836 SDOperand Ops
[] = { N0
, N1
, Tmp2
, N3
, InFlag
};
839 default: assert(false && "Illegal conditional move type!");
848 return CurDAG
->SelectNodeTo(Op
.Val
, Opc
, VT
, Ops
, 5);
851 return SelectCode(Op
);
854 /// createARMISelDag - This pass converts a legalized DAG into a
855 /// ARM-specific DAG, ready for instruction scheduling.
857 FunctionPass
*llvm::createARMISelDag(ARMTargetMachine
&TM
) {
858 return new ARMDAGToDAGISel(TM
);