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 "ARMAddressingModes.h"
16 #include "ARMConstantPoolValue.h"
17 #include "ARMISelLowering.h"
18 #include "ARMTargetMachine.h"
19 #include "llvm/CallingConv.h"
20 #include "llvm/Constants.h"
21 #include "llvm/DerivedTypes.h"
22 #include "llvm/Function.h"
23 #include "llvm/Intrinsics.h"
24 #include "llvm/CodeGen/MachineFrameInfo.h"
25 #include "llvm/CodeGen/MachineFunction.h"
26 #include "llvm/CodeGen/MachineInstrBuilder.h"
27 #include "llvm/CodeGen/SelectionDAG.h"
28 #include "llvm/CodeGen/SelectionDAGISel.h"
29 #include "llvm/Target/TargetLowering.h"
30 #include "llvm/Target/TargetOptions.h"
31 #include "llvm/Support/Compiler.h"
32 #include "llvm/Support/Debug.h"
35 //===--------------------------------------------------------------------===//
36 /// ARMDAGToDAGISel - ARM specific code to select ARM machine
37 /// instructions for SelectionDAG operations.
40 class ARMDAGToDAGISel
: public SelectionDAGISel
{
43 /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
44 /// make the right decision when generating code for different targets.
45 const ARMSubtarget
*Subtarget
;
48 explicit ARMDAGToDAGISel(ARMTargetMachine
&tm
)
49 : SelectionDAGISel(tm
), TM(tm
),
50 Subtarget(&TM
.getSubtarget
<ARMSubtarget
>()) {
53 virtual const char *getPassName() const {
54 return "ARM Instruction Selection";
57 SDNode
*Select(SDValue Op
);
58 virtual void InstructionSelect();
59 bool SelectAddrMode2(SDValue Op
, SDValue N
, SDValue
&Base
,
60 SDValue
&Offset
, SDValue
&Opc
);
61 bool SelectAddrMode2Offset(SDValue Op
, SDValue N
,
62 SDValue
&Offset
, SDValue
&Opc
);
63 bool SelectAddrMode3(SDValue Op
, SDValue N
, SDValue
&Base
,
64 SDValue
&Offset
, SDValue
&Opc
);
65 bool SelectAddrMode3Offset(SDValue Op
, SDValue N
,
66 SDValue
&Offset
, SDValue
&Opc
);
67 bool SelectAddrMode5(SDValue Op
, SDValue N
, SDValue
&Base
,
70 bool SelectAddrModePC(SDValue Op
, SDValue N
, SDValue
&Offset
,
73 bool SelectThumbAddrModeRR(SDValue Op
, SDValue N
, SDValue
&Base
,
75 bool SelectThumbAddrModeRI5(SDValue Op
, SDValue N
, unsigned Scale
,
76 SDValue
&Base
, SDValue
&OffImm
,
78 bool SelectThumbAddrModeS1(SDValue Op
, SDValue N
, SDValue
&Base
,
79 SDValue
&OffImm
, SDValue
&Offset
);
80 bool SelectThumbAddrModeS2(SDValue Op
, SDValue N
, SDValue
&Base
,
81 SDValue
&OffImm
, SDValue
&Offset
);
82 bool SelectThumbAddrModeS4(SDValue Op
, SDValue N
, SDValue
&Base
,
83 SDValue
&OffImm
, SDValue
&Offset
);
84 bool SelectThumbAddrModeSP(SDValue Op
, SDValue N
, SDValue
&Base
,
87 bool SelectShifterOperandReg(SDValue Op
, SDValue N
, SDValue
&A
,
88 SDValue
&B
, SDValue
&C
);
90 // Include the pieces autogenerated from the target description.
91 #include "ARMGenDAGISel.inc"
95 void ARMDAGToDAGISel::InstructionSelect() {
99 CurDAG
->RemoveDeadNodes();
102 bool ARMDAGToDAGISel::SelectAddrMode2(SDValue Op
, SDValue N
,
103 SDValue
&Base
, SDValue
&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
->getZExtValue();
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
->getZExtValue();
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
->getZExtValue();
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
->getZExtValue();
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(SDValue Op
, SDValue N
,
211 SDValue
&Offset
, SDValue
&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
->getZExtValue();
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
->getZExtValue();
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(SDValue Op
, SDValue N
,
250 SDValue
&Base
, SDValue
&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
->getZExtValue();
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(SDValue Op
, SDValue N
,
300 SDValue
&Offset
, SDValue
&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
->getZExtValue();
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(SDValue Op
, SDValue N
,
323 SDValue
&Base
, SDValue
&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
->getZExtValue();
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(SDValue Op
, SDValue N
,
369 SDValue
&Offset
, SDValue
&Label
) {
370 if (N
.getOpcode() == ARMISD::PIC_ADD
&& N
.hasOneUse()) {
371 Offset
= N
.getOperand(0);
372 SDValue N1
= N
.getOperand(1);
373 Label
= CurDAG
->getTargetConstant(cast
<ConstantSDNode
>(N1
)->getZExtValue(),
380 bool ARMDAGToDAGISel::SelectThumbAddrModeRR(SDValue Op
, SDValue N
,
381 SDValue
&Base
, SDValue
&Offset
){
382 // FIXME dl should come from the parent load or store, not the address
383 DebugLoc dl
= Op
.getDebugLoc();
384 if (N
.getOpcode() != ISD::ADD
) {
386 // We must materialize a zero in a reg! Returning a constant here
387 // wouldn't work without additional code to position the node within
388 // ISel's topological ordering in a place where ISel will process it
389 // normally. Instead, just explicitly issue a tMOVri8 node!
390 Offset
= SDValue(CurDAG
->getTargetNode(ARM::tMOVi8
, dl
, MVT::i32
,
391 CurDAG
->getTargetConstant(0, MVT::i32
)), 0);
395 Base
= N
.getOperand(0);
396 Offset
= N
.getOperand(1);
401 ARMDAGToDAGISel::SelectThumbAddrModeRI5(SDValue Op
, SDValue N
,
402 unsigned Scale
, SDValue
&Base
,
403 SDValue
&OffImm
, SDValue
&Offset
) {
405 SDValue TmpBase
, TmpOffImm
;
406 if (SelectThumbAddrModeSP(Op
, N
, TmpBase
, TmpOffImm
))
407 return false; // We want to select tLDRspi / tSTRspi instead.
408 if (N
.getOpcode() == ARMISD::Wrapper
&&
409 N
.getOperand(0).getOpcode() == ISD::TargetConstantPool
)
410 return false; // We want to select tLDRpci instead.
413 if (N
.getOpcode() != ISD::ADD
) {
414 Base
= (N
.getOpcode() == ARMISD::Wrapper
) ? N
.getOperand(0) : N
;
415 Offset
= CurDAG
->getRegister(0, MVT::i32
);
416 OffImm
= CurDAG
->getTargetConstant(0, MVT::i32
);
420 // Thumb does not have [sp, r] address mode.
421 RegisterSDNode
*LHSR
= dyn_cast
<RegisterSDNode
>(N
.getOperand(0));
422 RegisterSDNode
*RHSR
= dyn_cast
<RegisterSDNode
>(N
.getOperand(1));
423 if ((LHSR
&& LHSR
->getReg() == ARM::SP
) ||
424 (RHSR
&& RHSR
->getReg() == ARM::SP
)) {
426 Offset
= CurDAG
->getRegister(0, MVT::i32
);
427 OffImm
= CurDAG
->getTargetConstant(0, MVT::i32
);
431 // If the RHS is + imm5 * scale, fold into addr mode.
432 if (ConstantSDNode
*RHS
= dyn_cast
<ConstantSDNode
>(N
.getOperand(1))) {
433 int RHSC
= (int)RHS
->getZExtValue();
434 if ((RHSC
& (Scale
-1)) == 0) { // The constant is implicitly multiplied.
436 if (RHSC
>= 0 && RHSC
< 32) {
437 Base
= N
.getOperand(0);
438 Offset
= CurDAG
->getRegister(0, MVT::i32
);
439 OffImm
= CurDAG
->getTargetConstant(RHSC
, MVT::i32
);
445 Base
= N
.getOperand(0);
446 Offset
= N
.getOperand(1);
447 OffImm
= CurDAG
->getTargetConstant(0, MVT::i32
);
451 bool ARMDAGToDAGISel::SelectThumbAddrModeS1(SDValue Op
, SDValue N
,
452 SDValue
&Base
, SDValue
&OffImm
,
454 return SelectThumbAddrModeRI5(Op
, N
, 1, Base
, OffImm
, Offset
);
457 bool ARMDAGToDAGISel::SelectThumbAddrModeS2(SDValue Op
, SDValue N
,
458 SDValue
&Base
, SDValue
&OffImm
,
460 return SelectThumbAddrModeRI5(Op
, N
, 2, Base
, OffImm
, Offset
);
463 bool ARMDAGToDAGISel::SelectThumbAddrModeS4(SDValue Op
, SDValue N
,
464 SDValue
&Base
, SDValue
&OffImm
,
466 return SelectThumbAddrModeRI5(Op
, N
, 4, Base
, OffImm
, Offset
);
469 bool ARMDAGToDAGISel::SelectThumbAddrModeSP(SDValue Op
, SDValue N
,
470 SDValue
&Base
, SDValue
&OffImm
) {
471 if (N
.getOpcode() == ISD::FrameIndex
) {
472 int FI
= cast
<FrameIndexSDNode
>(N
)->getIndex();
473 Base
= CurDAG
->getTargetFrameIndex(FI
, TLI
.getPointerTy());
474 OffImm
= CurDAG
->getTargetConstant(0, MVT::i32
);
478 if (N
.getOpcode() != ISD::ADD
)
481 RegisterSDNode
*LHSR
= dyn_cast
<RegisterSDNode
>(N
.getOperand(0));
482 if (N
.getOperand(0).getOpcode() == ISD::FrameIndex
||
483 (LHSR
&& LHSR
->getReg() == ARM::SP
)) {
484 // If the RHS is + imm8 * scale, fold into addr mode.
485 if (ConstantSDNode
*RHS
= dyn_cast
<ConstantSDNode
>(N
.getOperand(1))) {
486 int RHSC
= (int)RHS
->getZExtValue();
487 if ((RHSC
& 3) == 0) { // The constant is implicitly multiplied.
489 if (RHSC
>= 0 && RHSC
< 256) {
490 Base
= N
.getOperand(0);
491 if (Base
.getOpcode() == ISD::FrameIndex
) {
492 int FI
= cast
<FrameIndexSDNode
>(Base
)->getIndex();
493 Base
= CurDAG
->getTargetFrameIndex(FI
, TLI
.getPointerTy());
495 OffImm
= CurDAG
->getTargetConstant(RHSC
, MVT::i32
);
505 bool ARMDAGToDAGISel::SelectShifterOperandReg(SDValue Op
,
510 ARM_AM::ShiftOpc ShOpcVal
= ARM_AM::getShiftOpcForNode(N
);
512 // Don't match base register only case. That is matched to a separate
513 // lower complexity pattern with explicit register operand.
514 if (ShOpcVal
== ARM_AM::no_shift
) return false;
516 BaseReg
= N
.getOperand(0);
517 unsigned ShImmVal
= 0;
518 if (ConstantSDNode
*RHS
= dyn_cast
<ConstantSDNode
>(N
.getOperand(1))) {
519 ShReg
= CurDAG
->getRegister(0, MVT::i32
);
520 ShImmVal
= RHS
->getZExtValue() & 31;
522 ShReg
= N
.getOperand(1);
524 Opc
= CurDAG
->getTargetConstant(ARM_AM::getSORegOpc(ShOpcVal
, ShImmVal
),
529 /// getAL - Returns a ARMCC::AL immediate node.
530 static inline SDValue
getAL(SelectionDAG
*CurDAG
) {
531 return CurDAG
->getTargetConstant((uint64_t)ARMCC::AL
, MVT::i32
);
535 SDNode
*ARMDAGToDAGISel::Select(SDValue Op
) {
536 SDNode
*N
= Op
.getNode();
537 DebugLoc dl
= N
->getDebugLoc();
539 if (N
->isMachineOpcode())
540 return NULL
; // Already selected.
542 switch (N
->getOpcode()) {
544 case ISD::Constant
: {
545 unsigned Val
= cast
<ConstantSDNode
>(N
)->getZExtValue();
547 if (Subtarget
->isThumb())
548 UseCP
= (Val
> 255 && // MOV
549 ~Val
> 255 && // MOV + MVN
550 !ARM_AM::isThumbImmShiftedVal(Val
)); // MOV + LSL
552 UseCP
= (ARM_AM::getSOImmVal(Val
) == -1 && // MOV
553 ARM_AM::getSOImmVal(~Val
) == -1 && // MVN
554 !ARM_AM::isSOImmTwoPartVal(Val
)); // two instrs.
557 CurDAG
->getTargetConstantPool(ConstantInt::get(Type::Int32Ty
, Val
),
561 if (Subtarget
->isThumb())
562 ResNode
= CurDAG
->getTargetNode(ARM::tLDRcp
, dl
, MVT::i32
, MVT::Other
,
563 CPIdx
, CurDAG
->getEntryNode());
567 CurDAG
->getRegister(0, MVT::i32
),
568 CurDAG
->getTargetConstant(0, MVT::i32
),
570 CurDAG
->getRegister(0, MVT::i32
),
571 CurDAG
->getEntryNode()
573 ResNode
=CurDAG
->getTargetNode(ARM::LDRcp
, dl
, MVT::i32
, MVT::Other
,
576 ReplaceUses(Op
, SDValue(ResNode
, 0));
580 // Other cases are autogenerated.
583 case ISD::FrameIndex
: {
584 // Selects to ADDri FI, 0 which in turn will become ADDri SP, imm.
585 int FI
= cast
<FrameIndexSDNode
>(N
)->getIndex();
586 SDValue TFI
= CurDAG
->getTargetFrameIndex(FI
, TLI
.getPointerTy());
587 if (Subtarget
->isThumb()) {
588 return CurDAG
->SelectNodeTo(N
, ARM::tADDrSPi
, MVT::i32
, TFI
,
589 CurDAG
->getTargetConstant(0, MVT::i32
));
591 SDValue Ops
[] = { TFI
, CurDAG
->getTargetConstant(0, MVT::i32
),
592 getAL(CurDAG
), CurDAG
->getRegister(0, MVT::i32
),
593 CurDAG
->getRegister(0, MVT::i32
) };
594 return CurDAG
->SelectNodeTo(N
, ARM::ADDri
, MVT::i32
, Ops
, 5);
598 if (!Subtarget
->isThumb())
600 // Select add sp, c to tADDhirr.
601 SDValue N0
= Op
.getOperand(0);
602 SDValue N1
= Op
.getOperand(1);
603 RegisterSDNode
*LHSR
= dyn_cast
<RegisterSDNode
>(Op
.getOperand(0));
604 RegisterSDNode
*RHSR
= dyn_cast
<RegisterSDNode
>(Op
.getOperand(1));
605 if (LHSR
&& LHSR
->getReg() == ARM::SP
) {
607 std::swap(LHSR
, RHSR
);
609 if (RHSR
&& RHSR
->getReg() == ARM::SP
) {
610 SDValue Val
= SDValue(CurDAG
->getTargetNode(ARM::tMOVlor2hir
, dl
,
611 Op
.getValueType(), N0
, N0
), 0);
612 return CurDAG
->SelectNodeTo(N
, ARM::tADDhirr
, Op
.getValueType(), Val
, N1
);
617 if (Subtarget
->isThumb())
619 if (ConstantSDNode
*C
= dyn_cast
<ConstantSDNode
>(Op
.getOperand(1))) {
620 unsigned RHSV
= C
->getZExtValue();
622 if (isPowerOf2_32(RHSV
-1)) { // 2^n+1?
623 SDValue V
= Op
.getOperand(0);
624 unsigned ShImm
= ARM_AM::getSORegOpc(ARM_AM::lsl
, Log2_32(RHSV
-1));
625 SDValue Ops
[] = { V
, V
, CurDAG
->getRegister(0, MVT::i32
),
626 CurDAG
->getTargetConstant(ShImm
, MVT::i32
),
627 getAL(CurDAG
), CurDAG
->getRegister(0, MVT::i32
),
628 CurDAG
->getRegister(0, MVT::i32
) };
629 return CurDAG
->SelectNodeTo(N
, ARM::ADDrs
, MVT::i32
, Ops
, 7);
631 if (isPowerOf2_32(RHSV
+1)) { // 2^n-1?
632 SDValue V
= Op
.getOperand(0);
633 unsigned ShImm
= ARM_AM::getSORegOpc(ARM_AM::lsl
, Log2_32(RHSV
+1));
634 SDValue Ops
[] = { V
, V
, CurDAG
->getRegister(0, MVT::i32
),
635 CurDAG
->getTargetConstant(ShImm
, MVT::i32
),
636 getAL(CurDAG
), CurDAG
->getRegister(0, MVT::i32
),
637 CurDAG
->getRegister(0, MVT::i32
) };
638 return CurDAG
->SelectNodeTo(N
, ARM::RSBrs
, MVT::i32
, Ops
, 7);
643 return CurDAG
->getTargetNode(ARM::FMRRD
, dl
, MVT::i32
, MVT::i32
,
644 Op
.getOperand(0), getAL(CurDAG
),
645 CurDAG
->getRegister(0, MVT::i32
));
646 case ISD::UMUL_LOHI
: {
647 SDValue 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
, dl
, MVT::i32
, MVT::i32
, Ops
, 5);
652 case ISD::SMUL_LOHI
: {
653 SDValue Ops
[] = { Op
.getOperand(0), Op
.getOperand(1),
654 getAL(CurDAG
), CurDAG
->getRegister(0, MVT::i32
),
655 CurDAG
->getRegister(0, MVT::i32
) };
656 return CurDAG
->getTargetNode(ARM::SMULL
, dl
, MVT::i32
, MVT::i32
, Ops
, 5);
659 LoadSDNode
*LD
= cast
<LoadSDNode
>(Op
);
660 ISD::MemIndexedMode AM
= LD
->getAddressingMode();
661 MVT LoadedVT
= LD
->getMemoryVT();
662 if (AM
!= ISD::UNINDEXED
) {
663 SDValue Offset
, AMOpc
;
664 bool isPre
= (AM
== ISD::PRE_INC
) || (AM
== ISD::PRE_DEC
);
667 if (LoadedVT
== MVT::i32
&&
668 SelectAddrMode2Offset(Op
, LD
->getOffset(), Offset
, AMOpc
)) {
669 Opcode
= isPre
? ARM::LDR_PRE
: ARM::LDR_POST
;
671 } else if (LoadedVT
== MVT::i16
&&
672 SelectAddrMode3Offset(Op
, LD
->getOffset(), Offset
, AMOpc
)) {
674 Opcode
= (LD
->getExtensionType() == ISD::SEXTLOAD
)
675 ? (isPre
? ARM::LDRSH_PRE
: ARM::LDRSH_POST
)
676 : (isPre
? ARM::LDRH_PRE
: ARM::LDRH_POST
);
677 } else if (LoadedVT
== MVT::i8
|| LoadedVT
== MVT::i1
) {
678 if (LD
->getExtensionType() == ISD::SEXTLOAD
) {
679 if (SelectAddrMode3Offset(Op
, LD
->getOffset(), Offset
, AMOpc
)) {
681 Opcode
= isPre
? ARM::LDRSB_PRE
: ARM::LDRSB_POST
;
684 if (SelectAddrMode2Offset(Op
, LD
->getOffset(), Offset
, AMOpc
)) {
686 Opcode
= isPre
? ARM::LDRB_PRE
: ARM::LDRB_POST
;
692 SDValue Chain
= LD
->getChain();
693 SDValue Base
= LD
->getBasePtr();
694 SDValue Ops
[]= { Base
, Offset
, AMOpc
, getAL(CurDAG
),
695 CurDAG
->getRegister(0, MVT::i32
), Chain
};
696 return CurDAG
->getTargetNode(Opcode
, dl
, MVT::i32
, MVT::i32
,
700 // Other cases are autogenerated.
703 case ARMISD::BRCOND
: {
704 // Pattern: (ARMbrcond:void (bb:Other):$dst, (imm:i32):$cc)
705 // Emits: (Bcc:void (bb:Other):$dst, (imm:i32):$cc)
706 // Pattern complexity = 6 cost = 1 size = 0
708 // Pattern: (ARMbrcond:void (bb:Other):$dst, (imm:i32):$cc)
709 // Emits: (tBcc:void (bb:Other):$dst, (imm:i32):$cc)
710 // Pattern complexity = 6 cost = 1 size = 0
712 unsigned Opc
= Subtarget
->isThumb() ? ARM::tBcc
: ARM::Bcc
;
713 SDValue Chain
= Op
.getOperand(0);
714 SDValue N1
= Op
.getOperand(1);
715 SDValue N2
= Op
.getOperand(2);
716 SDValue N3
= Op
.getOperand(3);
717 SDValue InFlag
= Op
.getOperand(4);
718 assert(N1
.getOpcode() == ISD::BasicBlock
);
719 assert(N2
.getOpcode() == ISD::Constant
);
720 assert(N3
.getOpcode() == ISD::Register
);
722 SDValue Tmp2
= CurDAG
->getTargetConstant(((unsigned)
723 cast
<ConstantSDNode
>(N2
)->getZExtValue()),
725 SDValue Ops
[] = { N1
, Tmp2
, N3
, Chain
, InFlag
};
726 SDNode
*ResNode
= CurDAG
->getTargetNode(Opc
, dl
, MVT::Other
,
728 Chain
= SDValue(ResNode
, 0);
729 if (Op
.getNode()->getNumValues() == 2) {
730 InFlag
= SDValue(ResNode
, 1);
731 ReplaceUses(SDValue(Op
.getNode(), 1), InFlag
);
733 ReplaceUses(SDValue(Op
.getNode(), 0), SDValue(Chain
.getNode(), Chain
.getResNo()));
737 bool isThumb
= Subtarget
->isThumb();
738 MVT VT
= Op
.getValueType();
739 SDValue N0
= Op
.getOperand(0);
740 SDValue N1
= Op
.getOperand(1);
741 SDValue N2
= Op
.getOperand(2);
742 SDValue N3
= Op
.getOperand(3);
743 SDValue InFlag
= Op
.getOperand(4);
744 assert(N2
.getOpcode() == ISD::Constant
);
745 assert(N3
.getOpcode() == ISD::Register
);
747 // Pattern: (ARMcmov:i32 GPR:i32:$false, so_reg:i32:$true, (imm:i32):$cc)
748 // Emits: (MOVCCs:i32 GPR:i32:$false, so_reg:i32:$true, (imm:i32):$cc)
749 // Pattern complexity = 18 cost = 1 size = 0
753 if (!isThumb
&& VT
== MVT::i32
&&
754 SelectShifterOperandReg(Op
, N1
, CPTmp0
, CPTmp1
, CPTmp2
)) {
755 SDValue Tmp2
= CurDAG
->getTargetConstant(((unsigned)
756 cast
<ConstantSDNode
>(N2
)->getZExtValue()),
758 SDValue Ops
[] = { N0
, CPTmp0
, CPTmp1
, CPTmp2
, Tmp2
, N3
, InFlag
};
759 return CurDAG
->SelectNodeTo(Op
.getNode(), ARM::MOVCCs
, MVT::i32
, Ops
, 7);
762 // Pattern: (ARMcmov:i32 GPR:i32:$false,
763 // (imm:i32)<<P:Predicate_so_imm>><<X:so_imm_XFORM>>:$true,
765 // Emits: (MOVCCi:i32 GPR:i32:$false,
766 // (so_imm_XFORM:i32 (imm:i32):$true), (imm:i32):$cc)
767 // Pattern complexity = 10 cost = 1 size = 0
768 if (VT
== MVT::i32
&&
769 N3
.getOpcode() == ISD::Constant
&&
770 Predicate_so_imm(N3
.getNode())) {
771 SDValue Tmp1
= CurDAG
->getTargetConstant(((unsigned)
772 cast
<ConstantSDNode
>(N1
)->getZExtValue()),
774 Tmp1
= Transform_so_imm_XFORM(Tmp1
.getNode());
775 SDValue Tmp2
= CurDAG
->getTargetConstant(((unsigned)
776 cast
<ConstantSDNode
>(N2
)->getZExtValue()),
778 SDValue Ops
[] = { N0
, Tmp1
, Tmp2
, N3
, InFlag
};
779 return CurDAG
->SelectNodeTo(Op
.getNode(), ARM::MOVCCi
, MVT::i32
, Ops
, 5);
782 // Pattern: (ARMcmov:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc)
783 // Emits: (MOVCCr:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc)
784 // Pattern complexity = 6 cost = 1 size = 0
786 // Pattern: (ARMcmov:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc)
787 // Emits: (tMOVCCr:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc)
788 // Pattern complexity = 6 cost = 11 size = 0
790 // Also FCPYScc and FCPYDcc.
791 SDValue Tmp2
= CurDAG
->getTargetConstant(((unsigned)
792 cast
<ConstantSDNode
>(N2
)->getZExtValue()),
794 SDValue Ops
[] = { N0
, N1
, Tmp2
, N3
, InFlag
};
796 switch (VT
.getSimpleVT()) {
797 default: assert(false && "Illegal conditional move type!");
800 Opc
= isThumb
? ARM::tMOVCCr
: ARM::MOVCCr
;
809 return CurDAG
->SelectNodeTo(Op
.getNode(), Opc
, VT
, Ops
, 5);
812 MVT VT
= Op
.getValueType();
813 SDValue N0
= Op
.getOperand(0);
814 SDValue N1
= Op
.getOperand(1);
815 SDValue N2
= Op
.getOperand(2);
816 SDValue N3
= Op
.getOperand(3);
817 SDValue InFlag
= Op
.getOperand(4);
818 assert(N2
.getOpcode() == ISD::Constant
);
819 assert(N3
.getOpcode() == ISD::Register
);
821 SDValue Tmp2
= CurDAG
->getTargetConstant(((unsigned)
822 cast
<ConstantSDNode
>(N2
)->getZExtValue()),
824 SDValue Ops
[] = { N0
, N1
, Tmp2
, N3
, InFlag
};
826 switch (VT
.getSimpleVT()) {
827 default: assert(false && "Illegal conditional move type!");
836 return CurDAG
->SelectNodeTo(Op
.getNode(), Opc
, VT
, Ops
, 5);
840 SDValue Chain
= Op
.getOperand(0);
841 SDValue N1
= Op
.getOperand(1);
842 SDValue N2
= Op
.getOperand(2);
843 FrameIndexSDNode
*FINode
= dyn_cast
<FrameIndexSDNode
>(N1
);
844 // FIXME: handle VLAs.
846 ReplaceUses(Op
.getValue(0), Chain
);
849 if (N2
.getOpcode() == ARMISD::PIC_ADD
&& isa
<LoadSDNode
>(N2
.getOperand(0)))
850 N2
= N2
.getOperand(0);
851 LoadSDNode
*Ld
= dyn_cast
<LoadSDNode
>(N2
);
853 ReplaceUses(Op
.getValue(0), Chain
);
856 SDValue BasePtr
= Ld
->getBasePtr();
857 assert(BasePtr
.getOpcode() == ARMISD::Wrapper
&&
858 isa
<ConstantPoolSDNode
>(BasePtr
.getOperand(0)) &&
859 "llvm.dbg.variable should be a constantpool node");
860 ConstantPoolSDNode
*CP
= cast
<ConstantPoolSDNode
>(BasePtr
.getOperand(0));
862 if (CP
->isMachineConstantPoolEntry()) {
863 ARMConstantPoolValue
*ACPV
= (ARMConstantPoolValue
*)CP
->getMachineCPVal();
866 GV
= dyn_cast
<GlobalValue
>(CP
->getConstVal());
868 ReplaceUses(Op
.getValue(0), Chain
);
872 SDValue Tmp1
= CurDAG
->getTargetFrameIndex(FINode
->getIndex(),
874 SDValue Tmp2
= CurDAG
->getTargetGlobalAddress(GV
, TLI
.getPointerTy());
875 SDValue Ops
[] = { Tmp1
, Tmp2
, Chain
};
876 return CurDAG
->getTargetNode(TargetInstrInfo::DECLARE
, dl
,
881 return SelectCode(Op
);
884 /// createARMISelDag - This pass converts a legalized DAG into a
885 /// ARM-specific DAG, ready for instruction scheduling.
887 FunctionPass
*llvm::createARMISelDag(ARMTargetMachine
&TM
) {
888 return new ARMDAGToDAGISel(TM
);