ARMISelDAGToDAG.cpp revision 8c1a73ad3ffbc121a251b93b0fb4e64187f90645
1//===-- ARMISelDAGToDAG.cpp - A dag to dag inst selector for ARM ----------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
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.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines an instruction selector for the ARM target.
11//
12//===----------------------------------------------------------------------===//
13
14#include "ARM.h"
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/Support/Debug.h"
31#include <iostream>
32using namespace llvm;
33
34//===--------------------------------------------------------------------===//
35/// ARMDAGToDAGISel - ARM specific code to select ARM machine
36/// instructions for SelectionDAG operations.
37///
38namespace {
39class ARMDAGToDAGISel : public SelectionDAGISel {
40  ARMTargetLowering Lowering;
41
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;
45
46public:
47  ARMDAGToDAGISel(ARMTargetMachine &TM)
48    : SelectionDAGISel(Lowering), Lowering(TM),
49    Subtarget(&TM.getSubtarget<ARMSubtarget>()) {
50  }
51
52  virtual const char *getPassName() const {
53    return "ARM Instruction Selection";
54  }
55
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,
67                       SDOperand &Offset);
68
69  bool SelectAddrModePC(SDOperand Op, SDOperand N, SDOperand &Offset,
70                         SDOperand &Label);
71
72  bool SelectThumbAddrModeRR(SDOperand Op, SDOperand N, SDOperand &Base,
73                             SDOperand &Offset);
74  bool SelectThumbAddrModeRI5(SDOperand Op, SDOperand N, unsigned Scale,
75                              SDOperand &Base, SDOperand &OffImm,
76                              SDOperand &Offset);
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,
84                             SDOperand &OffImm);
85
86  bool SelectShifterOperandReg(SDOperand Op, SDOperand N, SDOperand &A,
87                               SDOperand &B, SDOperand &C);
88
89  // Include the pieces autogenerated from the target description.
90#include "ARMGenDAGISel.inc"
91};
92}
93
94void ARMDAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
95  DEBUG(BB->dump());
96
97  DAG.setRoot(SelectRoot(DAG.getRoot()));
98  DAG.RemoveDeadNodes();
99
100  ScheduleAndEmitDAG(DAG);
101}
102
103bool ARMDAGToDAGISel::SelectAddrMode2(SDOperand Op, SDOperand N,
104                                      SDOperand &Base, SDOperand &Offset,
105                                      SDOperand &Opc) {
106  if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::SUB) {
107    Base = N;
108    if (N.getOpcode() == ISD::FrameIndex) {
109      int FI = cast<FrameIndexSDNode>(N)->getIndex();
110      Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy());
111    } else if (N.getOpcode() == ARMISD::Wrapper) {
112      Base = N.getOperand(0);
113    }
114    Offset = CurDAG->getRegister(0, MVT::i32);
115    Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(ARM_AM::add, 0,
116                                                      ARM_AM::no_shift),
117                                    MVT::i32);
118    return true;
119  }
120
121  // Match simple R +/- imm12 operands.
122  if (N.getOpcode() == ISD::ADD)
123    if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
124      int RHSC = (int)RHS->getValue();
125      if ((RHSC >= 0 && RHSC < 0x1000) ||
126          (RHSC < 0 && RHSC > -0x1000)) { // 12 bits.
127        Base = N.getOperand(0);
128        if (Base.getOpcode() == ISD::FrameIndex) {
129          int FI = cast<FrameIndexSDNode>(Base)->getIndex();
130          Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy());
131        }
132        Offset = CurDAG->getRegister(0, MVT::i32);
133
134        ARM_AM::AddrOpc AddSub = ARM_AM::add;
135        if (RHSC < 0) {
136          AddSub = ARM_AM::sub;
137          RHSC = - RHSC;
138        }
139        Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, RHSC,
140                                                          ARM_AM::no_shift),
141                                        MVT::i32);
142        return true;
143      }
144    }
145
146  // Otherwise this is R +/- [possibly shifted] R
147  ARM_AM::AddrOpc AddSub = N.getOpcode() == ISD::ADD ? ARM_AM::add:ARM_AM::sub;
148  ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOperand(1));
149  unsigned ShAmt = 0;
150
151  Base   = N.getOperand(0);
152  Offset = N.getOperand(1);
153
154  if (ShOpcVal != ARM_AM::no_shift) {
155    // Check to see if the RHS of the shift is a constant, if not, we can't fold
156    // it.
157    if (ConstantSDNode *Sh =
158           dyn_cast<ConstantSDNode>(N.getOperand(1).getOperand(1))) {
159      ShAmt = Sh->getValue();
160      Offset = N.getOperand(1).getOperand(0);
161    } else {
162      ShOpcVal = ARM_AM::no_shift;
163    }
164  }
165
166  // Try matching (R shl C) + (R).
167  if (N.getOpcode() == ISD::ADD && ShOpcVal == ARM_AM::no_shift) {
168    ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOperand(0));
169    if (ShOpcVal != ARM_AM::no_shift) {
170      // Check to see if the RHS of the shift is a constant, if not, we can't
171      // fold it.
172      if (ConstantSDNode *Sh =
173          dyn_cast<ConstantSDNode>(N.getOperand(0).getOperand(1))) {
174        ShAmt = Sh->getValue();
175        Offset = N.getOperand(0).getOperand(0);
176        Base = N.getOperand(1);
177      } else {
178        ShOpcVal = ARM_AM::no_shift;
179      }
180    }
181  }
182
183  Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, ShOpcVal),
184                                  MVT::i32);
185  return true;
186}
187
188bool ARMDAGToDAGISel::SelectAddrMode2Offset(SDOperand Op, SDOperand N,
189                                            SDOperand &Offset, SDOperand &Opc) {
190  unsigned Opcode = Op.getOpcode();
191  ISD::MemIndexedMode AM = (Opcode == ISD::LOAD)
192    ? cast<LoadSDNode>(Op)->getAddressingMode()
193    : cast<StoreSDNode>(Op)->getAddressingMode();
194  ARM_AM::AddrOpc AddSub = (AM == ISD::PRE_INC || AM == ISD::POST_INC)
195    ? ARM_AM::add : ARM_AM::sub;
196  if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N)) {
197    int Val = (int)C->getValue();
198    if (Val >= 0 && Val < 0x1000) { // 12 bits.
199      Offset = CurDAG->getRegister(0, MVT::i32);
200      Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, Val,
201                                                        ARM_AM::no_shift),
202                                      MVT::i32);
203      return true;
204    }
205  }
206
207  Offset = N;
208  ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N);
209  unsigned ShAmt = 0;
210  if (ShOpcVal != ARM_AM::no_shift) {
211    // Check to see if the RHS of the shift is a constant, if not, we can't fold
212    // it.
213    if (ConstantSDNode *Sh = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
214      ShAmt = Sh->getValue();
215      Offset = N.getOperand(0);
216    } else {
217      ShOpcVal = ARM_AM::no_shift;
218    }
219  }
220
221  Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, ShOpcVal),
222                                  MVT::i32);
223  return true;
224}
225
226
227bool ARMDAGToDAGISel::SelectAddrMode3(SDOperand Op, SDOperand N,
228                                      SDOperand &Base, SDOperand &Offset,
229                                      SDOperand &Opc) {
230  if (N.getOpcode() == ISD::SUB) {
231    // X - C  is canonicalize to X + -C, no need to handle it here.
232    Base = N.getOperand(0);
233    Offset = N.getOperand(1);
234    Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::sub, 0),MVT::i32);
235    return true;
236  }
237
238  if (N.getOpcode() != ISD::ADD) {
239    Base = N;
240    if (N.getOpcode() == ISD::FrameIndex) {
241      int FI = cast<FrameIndexSDNode>(N)->getIndex();
242      Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy());
243    }
244    Offset = CurDAG->getRegister(0, MVT::i32);
245    Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::add, 0),MVT::i32);
246    return true;
247  }
248
249  // If the RHS is +/- imm8, fold into addr mode.
250  if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
251    int RHSC = (int)RHS->getValue();
252    if ((RHSC >= 0 && RHSC < 256) ||
253        (RHSC < 0 && RHSC > -256)) { // note -256 itself isn't allowed.
254      Base = N.getOperand(0);
255      if (Base.getOpcode() == ISD::FrameIndex) {
256        int FI = cast<FrameIndexSDNode>(Base)->getIndex();
257        Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy());
258      }
259      Offset = CurDAG->getRegister(0, MVT::i32);
260
261      ARM_AM::AddrOpc AddSub = ARM_AM::add;
262      if (RHSC < 0) {
263        AddSub = ARM_AM::sub;
264        RHSC = - RHSC;
265      }
266      Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(AddSub, RHSC),MVT::i32);
267      return true;
268    }
269  }
270
271  Base = N.getOperand(0);
272  Offset = N.getOperand(1);
273  Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::add, 0), MVT::i32);
274  return true;
275}
276
277bool ARMDAGToDAGISel::SelectAddrMode3Offset(SDOperand Op, SDOperand N,
278                                            SDOperand &Offset, SDOperand &Opc) {
279  unsigned Opcode = Op.getOpcode();
280  ISD::MemIndexedMode AM = (Opcode == ISD::LOAD)
281    ? cast<LoadSDNode>(Op)->getAddressingMode()
282    : cast<StoreSDNode>(Op)->getAddressingMode();
283  ARM_AM::AddrOpc AddSub = (AM == ISD::PRE_INC || AM == ISD::POST_INC)
284    ? ARM_AM::add : ARM_AM::sub;
285  if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N)) {
286    int Val = (int)C->getValue();
287    if (Val >= 0 && Val < 256) {
288      Offset = CurDAG->getRegister(0, MVT::i32);
289      Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(AddSub, Val), MVT::i32);
290      return true;
291    }
292  }
293
294  Offset = N;
295  Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(AddSub, 0), MVT::i32);
296  return true;
297}
298
299
300bool ARMDAGToDAGISel::SelectAddrMode5(SDOperand Op, SDOperand N,
301                                      SDOperand &Base, SDOperand &Offset) {
302  if (N.getOpcode() != ISD::ADD) {
303    Base = N;
304    if (N.getOpcode() == ISD::FrameIndex) {
305      int FI = cast<FrameIndexSDNode>(N)->getIndex();
306      Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy());
307    } else if (N.getOpcode() == ARMISD::Wrapper) {
308      Base = N.getOperand(0);
309    }
310    Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::add, 0),
311                                       MVT::i32);
312    return true;
313  }
314
315  // If the RHS is +/- imm8, fold into addr mode.
316  if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
317    int RHSC = (int)RHS->getValue();
318    if ((RHSC & 3) == 0) {  // The constant is implicitly multiplied by 4.
319      RHSC >>= 2;
320      if ((RHSC >= 0 && RHSC < 256) ||
321          (RHSC < 0 && RHSC > -256)) { // note -256 itself isn't allowed.
322        Base = N.getOperand(0);
323        if (Base.getOpcode() == ISD::FrameIndex) {
324          int FI = cast<FrameIndexSDNode>(Base)->getIndex();
325          Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy());
326        }
327
328        ARM_AM::AddrOpc AddSub = ARM_AM::add;
329        if (RHSC < 0) {
330          AddSub = ARM_AM::sub;
331          RHSC = - RHSC;
332        }
333        Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(AddSub, RHSC),
334                                           MVT::i32);
335        return true;
336      }
337    }
338  }
339
340  Base = N;
341  Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::add, 0),
342                                     MVT::i32);
343  return true;
344}
345
346bool ARMDAGToDAGISel::SelectAddrModePC(SDOperand Op, SDOperand N,
347                                        SDOperand &Offset, SDOperand &Label) {
348  if (N.getOpcode() == ARMISD::PIC_ADD && N.hasOneUse()) {
349    Offset = N.getOperand(0);
350    SDOperand N1 = N.getOperand(1);
351    Label  = CurDAG->getTargetConstant(cast<ConstantSDNode>(N1)->getValue(),
352                                       MVT::i32);
353    return true;
354  }
355  return false;
356}
357
358bool ARMDAGToDAGISel::SelectThumbAddrModeRR(SDOperand Op, SDOperand N,
359                                            SDOperand &Base, SDOperand &Offset){
360  if (N.getOpcode() != ISD::ADD) {
361    Base = N;
362    // We must materialize a zero in a reg! Returning an constant here won't
363    // work since its node is -1 so it won't get added to the selection queue.
364    // Explicitly issue a tMOVri8 node!
365    Offset = SDOperand(CurDAG->getTargetNode(ARM::tMOVri8, MVT::i32,
366                                    CurDAG->getTargetConstant(0, MVT::i32)), 0);
367    return true;
368  }
369
370  Base = N.getOperand(0);
371  Offset = N.getOperand(1);
372  return true;
373}
374
375bool
376ARMDAGToDAGISel::SelectThumbAddrModeRI5(SDOperand Op, SDOperand N,
377                                        unsigned Scale, SDOperand &Base,
378                                        SDOperand &OffImm, SDOperand &Offset) {
379  if (Scale == 4) {
380    SDOperand TmpBase, TmpOffImm;
381    if (SelectThumbAddrModeSP(Op, N, TmpBase, TmpOffImm))
382      return false;  // We want to select tLDRspi / tSTRspi instead.
383    if (N.getOpcode() == ARMISD::Wrapper &&
384        N.getOperand(0).getOpcode() == ISD::TargetConstantPool)
385      return false;  // We want to select tLDRpci instead.
386  }
387
388  if (N.getOpcode() != ISD::ADD) {
389    Base = (N.getOpcode() == ARMISD::Wrapper) ? N.getOperand(0) : N;
390    Offset = CurDAG->getRegister(0, MVT::i32);
391    OffImm = CurDAG->getTargetConstant(0, MVT::i32);
392    return true;
393  }
394
395  // Thumb does not have [sp, r] address mode.
396  RegisterSDNode *LHSR = dyn_cast<RegisterSDNode>(N.getOperand(0));
397  RegisterSDNode *RHSR = dyn_cast<RegisterSDNode>(N.getOperand(1));
398  if ((LHSR && LHSR->getReg() == ARM::SP) ||
399      (RHSR && RHSR->getReg() == ARM::SP)) {
400    Base = N;
401    Offset = CurDAG->getRegister(0, MVT::i32);
402    OffImm = CurDAG->getTargetConstant(0, MVT::i32);
403    return true;
404  }
405
406  // If the RHS is + imm5 * scale, fold into addr mode.
407  if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
408    int RHSC = (int)RHS->getValue();
409    if ((RHSC & (Scale-1)) == 0) {  // The constant is implicitly multiplied.
410      RHSC /= Scale;
411      if (RHSC >= 0 && RHSC < 32) {
412        Base = N.getOperand(0);
413        Offset = CurDAG->getRegister(0, MVT::i32);
414        OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32);
415        return true;
416      }
417    }
418  }
419
420  Base = N.getOperand(0);
421  Offset = N.getOperand(1);
422  OffImm = CurDAG->getTargetConstant(0, MVT::i32);
423  return true;
424}
425
426bool ARMDAGToDAGISel::SelectThumbAddrModeS1(SDOperand Op, SDOperand N,
427                                            SDOperand &Base, SDOperand &OffImm,
428                                            SDOperand &Offset) {
429  return SelectThumbAddrModeRI5(Op, N, 1, Base, OffImm, Offset);
430}
431
432bool ARMDAGToDAGISel::SelectThumbAddrModeS2(SDOperand Op, SDOperand N,
433                                            SDOperand &Base, SDOperand &OffImm,
434                                            SDOperand &Offset) {
435  return SelectThumbAddrModeRI5(Op, N, 2, Base, OffImm, Offset);
436}
437
438bool ARMDAGToDAGISel::SelectThumbAddrModeS4(SDOperand Op, SDOperand N,
439                                            SDOperand &Base, SDOperand &OffImm,
440                                            SDOperand &Offset) {
441  return SelectThumbAddrModeRI5(Op, N, 4, Base, OffImm, Offset);
442}
443
444bool ARMDAGToDAGISel::SelectThumbAddrModeSP(SDOperand Op, SDOperand N,
445                                           SDOperand &Base, SDOperand &OffImm) {
446  if (N.getOpcode() == ISD::FrameIndex) {
447    int FI = cast<FrameIndexSDNode>(N)->getIndex();
448    Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy());
449    OffImm = CurDAG->getTargetConstant(0, MVT::i32);
450    return true;
451  }
452
453  if (N.getOpcode() != ISD::ADD)
454    return false;
455
456  RegisterSDNode *LHSR = dyn_cast<RegisterSDNode>(N.getOperand(0));
457  if (N.getOperand(0).getOpcode() == ISD::FrameIndex ||
458      (LHSR && LHSR->getReg() == ARM::SP)) {
459    // If the RHS is + imm8 * scale, fold into addr mode.
460    if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
461      int RHSC = (int)RHS->getValue();
462      if ((RHSC & 3) == 0) {  // The constant is implicitly multiplied.
463        RHSC >>= 2;
464        if (RHSC >= 0 && RHSC < 256) {
465          Base = N.getOperand(0);
466          if (Base.getOpcode() == ISD::FrameIndex) {
467            int FI = cast<FrameIndexSDNode>(Base)->getIndex();
468            Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy());
469          }
470          OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32);
471          return true;
472        }
473      }
474    }
475  }
476
477  return false;
478}
479
480bool ARMDAGToDAGISel::SelectShifterOperandReg(SDOperand Op,
481                                              SDOperand N,
482                                              SDOperand &BaseReg,
483                                              SDOperand &ShReg,
484                                              SDOperand &Opc) {
485  ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N);
486
487  // Don't match base register only case. That is matched to a separate
488  // lower complexity pattern with explicit register operand.
489  if (ShOpcVal == ARM_AM::no_shift) return false;
490
491  BaseReg = N.getOperand(0);
492  unsigned ShImmVal = 0;
493  if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
494    ShReg = CurDAG->getRegister(0, MVT::i32);
495    ShImmVal = RHS->getValue() & 31;
496  } else {
497    ShReg = N.getOperand(1);
498  }
499  Opc = CurDAG->getTargetConstant(ARM_AM::getSORegOpc(ShOpcVal, ShImmVal),
500                                  MVT::i32);
501  return true;
502}
503
504
505SDNode *ARMDAGToDAGISel::Select(SDOperand Op) {
506  SDNode *N = Op.Val;
507  unsigned Opcode = N->getOpcode();
508
509  if (Opcode >= ISD::BUILTIN_OP_END && Opcode < ARMISD::FIRST_NUMBER)
510    return NULL;   // Already selected.
511
512  switch (N->getOpcode()) {
513  default: break;
514  case ISD::Constant: {
515    unsigned Val = cast<ConstantSDNode>(N)->getValue();
516    bool UseCP = true;
517    if (Subtarget->isThumb())
518      UseCP = (Val > 255 &&                          // MOV
519               ~Val > 255 &&                         // MOV + MVN
520               !ARM_AM::isThumbImmShiftedVal(Val));  // MOV + LSL
521    else
522      UseCP = (ARM_AM::getSOImmVal(Val) == -1 &&     // MOV
523               ARM_AM::getSOImmVal(~Val) == -1 &&    // MVN
524               !ARM_AM::isSOImmTwoPartVal(Val));     // two instrs.
525    if (UseCP) {
526      SDOperand CPIdx =
527        CurDAG->getTargetConstantPool(ConstantInt::get(Type::Int32Ty, Val),
528                                      TLI.getPointerTy());
529
530      SDNode *ResNode;
531      if (Subtarget->isThumb())
532        ResNode = CurDAG->getTargetNode(ARM::tLDRpci, MVT::i32, MVT::Other,
533                                        CPIdx, CurDAG->getEntryNode());
534      else {
535        SDOperand Ops[] = {
536          CPIdx,
537          CurDAG->getRegister(0, MVT::i32),
538          CurDAG->getTargetConstant(0, MVT::i32),
539          CurDAG->getEntryNode()
540        };
541        ResNode = CurDAG->getTargetNode(ARM::LDR, MVT::i32, MVT::Other, Ops, 4);
542      }
543      ReplaceUses(Op, SDOperand(ResNode, 0));
544      return NULL;
545    }
546
547    // Other cases are autogenerated.
548    break;
549  }
550  case ISD::FrameIndex: {
551    // Selects to ADDri FI, 0 which in turn will become ADDri SP, imm.
552    int FI = cast<FrameIndexSDNode>(N)->getIndex();
553    unsigned Opc = Subtarget->isThumb() ? ARM::tADDrSPi : ARM::ADDri;
554    SDOperand TFI = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy());
555    return CurDAG->SelectNodeTo(N, Opc, MVT::i32, TFI,
556                                CurDAG->getTargetConstant(0, MVT::i32));
557  }
558  case ISD::ADD: {
559    // Select add sp, c to tADDhirr.
560    SDOperand N0 = Op.getOperand(0);
561    SDOperand N1 = Op.getOperand(1);
562    RegisterSDNode *LHSR = dyn_cast<RegisterSDNode>(Op.getOperand(0));
563    RegisterSDNode *RHSR = dyn_cast<RegisterSDNode>(Op.getOperand(1));
564    if (LHSR && LHSR->getReg() == ARM::SP) {
565      std::swap(N0, N1);
566      std::swap(LHSR, RHSR);
567    }
568    if (RHSR && RHSR->getReg() == ARM::SP) {
569      AddToISelQueue(N0);
570      AddToISelQueue(N1);
571      return CurDAG->SelectNodeTo(N, ARM::tADDhirr, Op.getValueType(), N0, N1);
572    }
573    break;
574  }
575  case ISD::MUL:
576    if (Subtarget->isThumb())
577      break;
578    if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
579      unsigned RHSV = C->getValue();
580      if (!RHSV) break;
581      if (isPowerOf2_32(RHSV-1)) {  // 2^n+1?
582        SDOperand V = Op.getOperand(0);
583        AddToISelQueue(V);
584        unsigned ShImm = ARM_AM::getSORegOpc(ARM_AM::lsl, Log2_32(RHSV-1));
585        SDOperand Ops[] = { V, V, CurDAG->getRegister(0, MVT::i32),
586          CurDAG->getTargetConstant(ShImm, MVT::i32)
587        };
588        return CurDAG->SelectNodeTo(N, ARM::ADDrs, MVT::i32, Ops, 4);
589      }
590      if (isPowerOf2_32(RHSV+1)) {  // 2^n-1?
591        SDOperand V = Op.getOperand(0);
592        AddToISelQueue(V);
593        unsigned ShImm = ARM_AM::getSORegOpc(ARM_AM::lsl, Log2_32(RHSV+1));
594        SDOperand Ops[] = { V, V, CurDAG->getRegister(0, MVT::i32),
595          CurDAG->getTargetConstant(ShImm, MVT::i32)
596        };
597        return CurDAG->SelectNodeTo(N, ARM::RSBrs, MVT::i32, Ops, 4);
598      }
599    }
600    break;
601  case ARMISD::FMRRD:
602    AddToISelQueue(Op.getOperand(0));
603    return CurDAG->getTargetNode(ARM::FMRRD, MVT::i32, MVT::i32,
604                                 Op.getOperand(0));
605  case ARMISD::MULHILOU:
606    AddToISelQueue(Op.getOperand(0));
607    AddToISelQueue(Op.getOperand(1));
608    return CurDAG->getTargetNode(ARM::UMULL, MVT::i32, MVT::i32,
609                                 Op.getOperand(0), Op.getOperand(1));
610  case ARMISD::MULHILOS:
611    AddToISelQueue(Op.getOperand(0));
612    AddToISelQueue(Op.getOperand(1));
613    return CurDAG->getTargetNode(ARM::SMULL, MVT::i32, MVT::i32,
614                                 Op.getOperand(0), Op.getOperand(1));
615  case ISD::LOAD: {
616    LoadSDNode *LD = cast<LoadSDNode>(Op);
617    ISD::MemIndexedMode AM = LD->getAddressingMode();
618    MVT::ValueType LoadedVT = LD->getLoadedVT();
619    if (AM != ISD::UNINDEXED) {
620      SDOperand Offset, AMOpc;
621      bool isPre = (AM == ISD::PRE_INC) || (AM == ISD::PRE_DEC);
622      unsigned Opcode = 0;
623      bool Match = false;
624      if (LoadedVT == MVT::i32 &&
625          SelectAddrMode2Offset(Op, LD->getOffset(), Offset, AMOpc)) {
626        Opcode = isPre ? ARM::LDR_PRE : ARM::LDR_POST;
627        Match = true;
628      } else if (LoadedVT == MVT::i16 &&
629                 SelectAddrMode3Offset(Op, LD->getOffset(), Offset, AMOpc)) {
630        Match = true;
631        Opcode = (LD->getExtensionType() == ISD::SEXTLOAD)
632          ? (isPre ? ARM::LDRSH_PRE : ARM::LDRSH_POST)
633          : (isPre ? ARM::LDRH_PRE : ARM::LDRH_POST);
634      } else if (LoadedVT == MVT::i8 || LoadedVT == MVT::i1) {
635        if (LD->getExtensionType() == ISD::SEXTLOAD) {
636          if (SelectAddrMode3Offset(Op, LD->getOffset(), Offset, AMOpc)) {
637            Match = true;
638            Opcode = isPre ? ARM::LDRSB_PRE : ARM::LDRSB_POST;
639          }
640        } else {
641          if (SelectAddrMode2Offset(Op, LD->getOffset(), Offset, AMOpc)) {
642            Match = true;
643            Opcode = isPre ? ARM::LDRB_PRE : ARM::LDRB_POST;
644          }
645        }
646      }
647
648      if (Match) {
649        SDOperand Chain = LD->getChain();
650        SDOperand Base = LD->getBasePtr();
651        AddToISelQueue(Chain);
652        AddToISelQueue(Base);
653        AddToISelQueue(Offset);
654        SDOperand Ops[] = { Base, Offset, AMOpc, Chain };
655        return CurDAG->getTargetNode(Opcode, MVT::i32, MVT::i32,
656                                     MVT::Other, Ops, 4);
657      }
658    }
659    // Other cases are autogenerated.
660    break;
661  }
662  }
663
664  return SelectCode(Op);
665}
666
667/// createARMISelDag - This pass converts a legalized DAG into a
668/// ARM-specific DAG, ready for instruction scheduling.
669///
670FunctionPass *llvm::createARMISelDag(ARMTargetMachine &TM) {
671  return new ARMDAGToDAGISel(TM);
672}
673