ARMISelDAGToDAG.cpp revision ad0e465889d49f423436dc56d50c838df2672133
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 (LHSR && LHSR->getReg() == ARM::SP) {
458    // If the RHS is + imm8 * scale, fold into addr mode.
459    if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
460      int RHSC = (int)RHS->getValue();
461      if ((RHSC & 3) == 0) {  // The constant is implicitly multiplied.
462        RHSC >>= 2;
463        if (RHSC >= 0 && RHSC < 256) {
464          Base = N.getOperand(0);
465          OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32);
466          return true;
467        }
468      }
469    }
470  }
471
472  return false;
473}
474
475bool ARMDAGToDAGISel::SelectShifterOperandReg(SDOperand Op,
476                                              SDOperand N,
477                                              SDOperand &BaseReg,
478                                              SDOperand &ShReg,
479                                              SDOperand &Opc) {
480  ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N);
481
482  // Don't match base register only case. That is matched to a separate
483  // lower complexity pattern with explicit register operand.
484  if (ShOpcVal == ARM_AM::no_shift) return false;
485
486  BaseReg = N.getOperand(0);
487  unsigned ShImmVal = 0;
488  if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
489    ShReg = CurDAG->getRegister(0, MVT::i32);
490    ShImmVal = RHS->getValue() & 31;
491  } else {
492    ShReg = N.getOperand(1);
493  }
494  Opc = CurDAG->getTargetConstant(ARM_AM::getSORegOpc(ShOpcVal, ShImmVal),
495                                  MVT::i32);
496  return true;
497}
498
499
500SDNode *ARMDAGToDAGISel::Select(SDOperand Op) {
501  SDNode *N = Op.Val;
502  unsigned Opcode = N->getOpcode();
503
504  if (Opcode >= ISD::BUILTIN_OP_END && Opcode < ARMISD::FIRST_NUMBER)
505    return NULL;   // Already selected.
506
507  switch (N->getOpcode()) {
508  default: break;
509  case ISD::Constant: {
510    unsigned Val = cast<ConstantSDNode>(N)->getValue();
511    bool UseCP = true;
512    if (Subtarget->isThumb())
513      UseCP = (Val > 255 &&                          // MOV
514               ~Val > 255 &&                         // MOV + MVN
515               !ARM_AM::isThumbImmShiftedVal(Val));  // MOV + LSL
516    else
517      UseCP = (ARM_AM::getSOImmVal(Val) == -1 &&     // MOV
518               ARM_AM::getSOImmVal(~Val) == -1 &&    // MVN
519               !ARM_AM::isSOImmTwoPartVal(Val));     // two instrs.
520    if (UseCP) {
521      SDOperand CPIdx =
522        CurDAG->getTargetConstantPool(ConstantInt::get(Type::Int32Ty, Val),
523                                      TLI.getPointerTy());
524
525      SDNode *ResNode;
526      if (Subtarget->isThumb())
527        ResNode = CurDAG->getTargetNode(ARM::tLDRpci, MVT::i32, MVT::Other,
528                                        CPIdx, CurDAG->getEntryNode());
529      else {
530        SDOperand Ops[] = {
531          CPIdx,
532          CurDAG->getRegister(0, MVT::i32),
533          CurDAG->getTargetConstant(0, MVT::i32),
534          CurDAG->getEntryNode()
535        };
536        ResNode = CurDAG->getTargetNode(ARM::LDR, MVT::i32, MVT::Other, Ops, 4);
537      }
538      ReplaceUses(Op, SDOperand(ResNode, 0));
539      return NULL;
540    }
541
542    // Other cases are autogenerated.
543    break;
544  }
545  case ISD::FrameIndex: {
546    // Selects to ADDri FI, 0 which in turn will become ADDri SP, imm.
547    int FI = cast<FrameIndexSDNode>(N)->getIndex();
548    unsigned Opc = Subtarget->isThumb() ? ARM::tADDrSPi : ARM::ADDri;
549    SDOperand TFI = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy());
550    return CurDAG->SelectNodeTo(N, Opc, MVT::i32, TFI,
551                                CurDAG->getTargetConstant(0, MVT::i32));
552  }
553  case ISD::ADD: {
554    // Select add sp, c to tADDhirr.
555    SDOperand N0 = Op.getOperand(0);
556    SDOperand N1 = Op.getOperand(1);
557    RegisterSDNode *LHSR = dyn_cast<RegisterSDNode>(Op.getOperand(0));
558    RegisterSDNode *RHSR = dyn_cast<RegisterSDNode>(Op.getOperand(1));
559    if (LHSR && LHSR->getReg() == ARM::SP) {
560      std::swap(N0, N1);
561      std::swap(LHSR, RHSR);
562    }
563    if (RHSR && RHSR->getReg() == ARM::SP) {
564      AddToISelQueue(N0);
565      AddToISelQueue(N1);
566      return CurDAG->SelectNodeTo(N, ARM::tADDhirr, Op.getValueType(), N0, N1);
567    }
568    break;
569  }
570  case ISD::MUL:
571    if (Subtarget->isThumb())
572      break;
573    if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
574      unsigned RHSV = C->getValue();
575      if (!RHSV) break;
576      if (isPowerOf2_32(RHSV-1)) {  // 2^n+1?
577        SDOperand V = Op.getOperand(0);
578        AddToISelQueue(V);
579        unsigned ShImm = ARM_AM::getSORegOpc(ARM_AM::lsl, Log2_32(RHSV-1));
580        SDOperand Ops[] = { V, V, CurDAG->getRegister(0, MVT::i32),
581          CurDAG->getTargetConstant(ShImm, MVT::i32)
582        };
583        return CurDAG->SelectNodeTo(N, ARM::ADDrs, MVT::i32, Ops, 4);
584      }
585      if (isPowerOf2_32(RHSV+1)) {  // 2^n-1?
586        SDOperand V = Op.getOperand(0);
587        AddToISelQueue(V);
588        unsigned ShImm = ARM_AM::getSORegOpc(ARM_AM::lsl, Log2_32(RHSV+1));
589        SDOperand Ops[] = { V, V, CurDAG->getRegister(0, MVT::i32),
590          CurDAG->getTargetConstant(ShImm, MVT::i32)
591        };
592        return CurDAG->SelectNodeTo(N, ARM::RSBrs, MVT::i32, Ops, 4);
593      }
594    }
595    break;
596  case ARMISD::FMRRD:
597    AddToISelQueue(Op.getOperand(0));
598    return CurDAG->getTargetNode(ARM::FMRRD, MVT::i32, MVT::i32,
599                                 Op.getOperand(0));
600  case ARMISD::MULHILOU:
601    AddToISelQueue(Op.getOperand(0));
602    AddToISelQueue(Op.getOperand(1));
603    return CurDAG->getTargetNode(ARM::UMULL, MVT::i32, MVT::i32,
604                                 Op.getOperand(0), Op.getOperand(1));
605  case ARMISD::MULHILOS:
606    AddToISelQueue(Op.getOperand(0));
607    AddToISelQueue(Op.getOperand(1));
608    return CurDAG->getTargetNode(ARM::SMULL, MVT::i32, MVT::i32,
609                                 Op.getOperand(0), Op.getOperand(1));
610  case ISD::LOAD: {
611    LoadSDNode *LD = cast<LoadSDNode>(Op);
612    ISD::MemIndexedMode AM = LD->getAddressingMode();
613    MVT::ValueType LoadedVT = LD->getLoadedVT();
614    if (AM != ISD::UNINDEXED) {
615      SDOperand Offset, AMOpc;
616      bool isPre = (AM == ISD::PRE_INC) || (AM == ISD::PRE_DEC);
617      unsigned Opcode = 0;
618      bool Match = false;
619      if (LoadedVT == MVT::i32 &&
620          SelectAddrMode2Offset(Op, LD->getOffset(), Offset, AMOpc)) {
621        Opcode = isPre ? ARM::LDR_PRE : ARM::LDR_POST;
622        Match = true;
623      } else if (LoadedVT == MVT::i16 &&
624                 SelectAddrMode3Offset(Op, LD->getOffset(), Offset, AMOpc)) {
625        Match = true;
626        Opcode = (LD->getExtensionType() == ISD::SEXTLOAD)
627          ? (isPre ? ARM::LDRSH_PRE : ARM::LDRSH_POST)
628          : (isPre ? ARM::LDRH_PRE : ARM::LDRH_POST);
629      } else if (LoadedVT == MVT::i8 || LoadedVT == MVT::i1) {
630        if (LD->getExtensionType() == ISD::SEXTLOAD) {
631          if (SelectAddrMode3Offset(Op, LD->getOffset(), Offset, AMOpc)) {
632            Match = true;
633            Opcode = isPre ? ARM::LDRSB_PRE : ARM::LDRSB_POST;
634          }
635        } else {
636          if (SelectAddrMode2Offset(Op, LD->getOffset(), Offset, AMOpc)) {
637            Match = true;
638            Opcode = isPre ? ARM::LDRB_PRE : ARM::LDRB_POST;
639          }
640        }
641      }
642
643      if (Match) {
644        SDOperand Chain = LD->getChain();
645        SDOperand Base = LD->getBasePtr();
646        AddToISelQueue(Chain);
647        AddToISelQueue(Base);
648        AddToISelQueue(Offset);
649        SDOperand Ops[] = { Base, Offset, AMOpc, Chain };
650        return CurDAG->getTargetNode(Opcode, MVT::i32, MVT::i32,
651                                     MVT::Other, Ops, 4);
652      }
653    }
654    // Other cases are autogenerated.
655    break;
656  }
657  }
658
659  return SelectCode(Op);
660}
661
662/// createARMISelDag - This pass converts a legalized DAG into a
663/// ARM-specific DAG, ready for instruction scheduling.
664///
665FunctionPass *llvm::createARMISelDag(ARMTargetMachine &TM) {
666  return new ARMDAGToDAGISel(TM);
667}
668