Rename SDOperand to SDValue.
[oota-llvm.git] / lib / Target / ARM / ARMISelDAGToDAG.cpp
1 //===-- ARMISelDAGToDAG.cpp - A dag to dag inst selector for ARM ----------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // 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/Target/TargetLowering.h"
29 #include "llvm/Target/TargetOptions.h"
30 #include "llvm/Support/Compiler.h"
31 #include "llvm/Support/Debug.h"
32 using namespace llvm;
33
34 //===--------------------------------------------------------------------===//
35 /// ARMDAGToDAGISel - ARM specific code to select ARM machine
36 /// instructions for SelectionDAG operations.
37 ///
38 namespace {
39 class 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
46 public:
47   explicit 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(SDValue Op);
57   virtual void InstructionSelect(SelectionDAG &DAG);
58   bool SelectAddrMode2(SDValue Op, SDValue N, SDValue &Base,
59                        SDValue &Offset, SDValue &Opc);
60   bool SelectAddrMode2Offset(SDValue Op, SDValue N,
61                              SDValue &Offset, SDValue &Opc);
62   bool SelectAddrMode3(SDValue Op, SDValue N, SDValue &Base,
63                        SDValue &Offset, SDValue &Opc);
64   bool SelectAddrMode3Offset(SDValue Op, SDValue N,
65                              SDValue &Offset, SDValue &Opc);
66   bool SelectAddrMode5(SDValue Op, SDValue N, SDValue &Base,
67                        SDValue &Offset);
68
69   bool SelectAddrModePC(SDValue Op, SDValue N, SDValue &Offset,
70                          SDValue &Label);
71
72   bool SelectThumbAddrModeRR(SDValue Op, SDValue N, SDValue &Base,
73                              SDValue &Offset);
74   bool SelectThumbAddrModeRI5(SDValue Op, SDValue N, unsigned Scale,
75                               SDValue &Base, SDValue &OffImm,
76                               SDValue &Offset);
77   bool SelectThumbAddrModeS1(SDValue Op, SDValue N, SDValue &Base,
78                              SDValue &OffImm, SDValue &Offset);
79   bool SelectThumbAddrModeS2(SDValue Op, SDValue N, SDValue &Base,
80                              SDValue &OffImm, SDValue &Offset);
81   bool SelectThumbAddrModeS4(SDValue Op, SDValue N, SDValue &Base,
82                              SDValue &OffImm, SDValue &Offset);
83   bool SelectThumbAddrModeSP(SDValue Op, SDValue N, SDValue &Base,
84                              SDValue &OffImm);
85
86   bool SelectShifterOperandReg(SDValue Op, SDValue N, SDValue &A,
87                                SDValue &B, SDValue &C);
88   
89   // Include the pieces autogenerated from the target description.
90 #include "ARMGenDAGISel.inc"
91 };
92 }
93
94 void ARMDAGToDAGISel::InstructionSelect(SelectionDAG &DAG) {
95   DEBUG(BB->dump());
96
97   DAG.setRoot(SelectRoot(DAG.getRoot()));
98   DAG.RemoveDeadNodes();
99 }
100
101 bool ARMDAGToDAGISel::SelectAddrMode2(SDValue Op, SDValue N,
102                                       SDValue &Base, SDValue &Offset,
103                                       SDValue &Opc) {
104   if (N.getOpcode() == ISD::MUL) {
105     if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
106       // X * [3,5,9] -> X + X * [2,4,8] etc.
107       int RHSC = (int)RHS->getValue();
108       if (RHSC & 1) {
109         RHSC = RHSC & ~1;
110         ARM_AM::AddrOpc AddSub = ARM_AM::add;
111         if (RHSC < 0) {
112           AddSub = ARM_AM::sub;
113           RHSC = - RHSC;
114         }
115         if (isPowerOf2_32(RHSC)) {
116           unsigned ShAmt = Log2_32(RHSC);
117           Base = Offset = N.getOperand(0);
118           Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt,
119                                                             ARM_AM::lsl),
120                                           MVT::i32);
121           return true;
122         }
123       }
124     }
125   }
126
127   if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::SUB) {
128     Base = N;
129     if (N.getOpcode() == ISD::FrameIndex) {
130       int FI = cast<FrameIndexSDNode>(N)->getIndex();
131       Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy());
132     } else if (N.getOpcode() == ARMISD::Wrapper) {
133       Base = N.getOperand(0);
134     }
135     Offset = CurDAG->getRegister(0, MVT::i32);
136     Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(ARM_AM::add, 0,
137                                                       ARM_AM::no_shift),
138                                     MVT::i32);
139     return true;
140   }
141   
142   // Match simple R +/- imm12 operands.
143   if (N.getOpcode() == ISD::ADD)
144     if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
145       int RHSC = (int)RHS->getValue();
146       if ((RHSC >= 0 && RHSC < 0x1000) ||
147           (RHSC < 0 && RHSC > -0x1000)) { // 12 bits.
148         Base = N.getOperand(0);
149         if (Base.getOpcode() == ISD::FrameIndex) {
150           int FI = cast<FrameIndexSDNode>(Base)->getIndex();
151           Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy());
152         }
153         Offset = CurDAG->getRegister(0, MVT::i32);
154
155         ARM_AM::AddrOpc AddSub = ARM_AM::add;
156         if (RHSC < 0) {
157           AddSub = ARM_AM::sub;
158           RHSC = - RHSC;
159         }
160         Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, RHSC,
161                                                           ARM_AM::no_shift),
162                                         MVT::i32);
163         return true;
164       }
165     }
166   
167   // Otherwise this is R +/- [possibly shifted] R
168   ARM_AM::AddrOpc AddSub = N.getOpcode() == ISD::ADD ? ARM_AM::add:ARM_AM::sub;
169   ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOperand(1));
170   unsigned ShAmt = 0;
171   
172   Base   = N.getOperand(0);
173   Offset = N.getOperand(1);
174   
175   if (ShOpcVal != ARM_AM::no_shift) {
176     // Check to see if the RHS of the shift is a constant, if not, we can't fold
177     // it.
178     if (ConstantSDNode *Sh =
179            dyn_cast<ConstantSDNode>(N.getOperand(1).getOperand(1))) {
180       ShAmt = Sh->getValue();
181       Offset = N.getOperand(1).getOperand(0);
182     } else {
183       ShOpcVal = ARM_AM::no_shift;
184     }
185   }
186   
187   // Try matching (R shl C) + (R).
188   if (N.getOpcode() == ISD::ADD && ShOpcVal == ARM_AM::no_shift) {
189     ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOperand(0));
190     if (ShOpcVal != ARM_AM::no_shift) {
191       // Check to see if the RHS of the shift is a constant, if not, we can't
192       // fold it.
193       if (ConstantSDNode *Sh =
194           dyn_cast<ConstantSDNode>(N.getOperand(0).getOperand(1))) {
195         ShAmt = Sh->getValue();
196         Offset = N.getOperand(0).getOperand(0);
197         Base = N.getOperand(1);
198       } else {
199         ShOpcVal = ARM_AM::no_shift;
200       }
201     }
202   }
203   
204   Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, ShOpcVal),
205                                   MVT::i32);
206   return true;
207 }
208
209 bool ARMDAGToDAGISel::SelectAddrMode2Offset(SDValue Op, SDValue N,
210                                             SDValue &Offset, SDValue &Opc) {
211   unsigned Opcode = Op.getOpcode();
212   ISD::MemIndexedMode AM = (Opcode == ISD::LOAD)
213     ? cast<LoadSDNode>(Op)->getAddressingMode()
214     : cast<StoreSDNode>(Op)->getAddressingMode();
215   ARM_AM::AddrOpc AddSub = (AM == ISD::PRE_INC || AM == ISD::POST_INC)
216     ? ARM_AM::add : ARM_AM::sub;
217   if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N)) {
218     int Val = (int)C->getValue();
219     if (Val >= 0 && Val < 0x1000) { // 12 bits.
220       Offset = CurDAG->getRegister(0, MVT::i32);
221       Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, Val,
222                                                         ARM_AM::no_shift),
223                                       MVT::i32);
224       return true;
225     }
226   }
227
228   Offset = N;
229   ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N);
230   unsigned ShAmt = 0;
231   if (ShOpcVal != ARM_AM::no_shift) {
232     // Check to see if the RHS of the shift is a constant, if not, we can't fold
233     // it.
234     if (ConstantSDNode *Sh = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
235       ShAmt = Sh->getValue();
236       Offset = N.getOperand(0);
237     } else {
238       ShOpcVal = ARM_AM::no_shift;
239     }
240   }
241
242   Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, ShOpcVal),
243                                   MVT::i32);
244   return true;
245 }
246
247
248 bool ARMDAGToDAGISel::SelectAddrMode3(SDValue Op, SDValue N,
249                                       SDValue &Base, SDValue &Offset,
250                                       SDValue &Opc) {
251   if (N.getOpcode() == ISD::SUB) {
252     // X - C  is canonicalize to X + -C, no need to handle it here.
253     Base = N.getOperand(0);
254     Offset = N.getOperand(1);
255     Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::sub, 0),MVT::i32);
256     return true;
257   }
258   
259   if (N.getOpcode() != ISD::ADD) {
260     Base = N;
261     if (N.getOpcode() == ISD::FrameIndex) {
262       int FI = cast<FrameIndexSDNode>(N)->getIndex();
263       Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy());
264     }
265     Offset = CurDAG->getRegister(0, MVT::i32);
266     Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::add, 0),MVT::i32);
267     return true;
268   }
269   
270   // If the RHS is +/- imm8, fold into addr mode.
271   if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
272     int RHSC = (int)RHS->getValue();
273     if ((RHSC >= 0 && RHSC < 256) ||
274         (RHSC < 0 && RHSC > -256)) { // note -256 itself isn't allowed.
275       Base = N.getOperand(0);
276       if (Base.getOpcode() == ISD::FrameIndex) {
277         int FI = cast<FrameIndexSDNode>(Base)->getIndex();
278         Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy());
279       }
280       Offset = CurDAG->getRegister(0, MVT::i32);
281
282       ARM_AM::AddrOpc AddSub = ARM_AM::add;
283       if (RHSC < 0) {
284         AddSub = ARM_AM::sub;
285         RHSC = - RHSC;
286       }
287       Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(AddSub, RHSC),MVT::i32);
288       return true;
289     }
290   }
291   
292   Base = N.getOperand(0);
293   Offset = N.getOperand(1);
294   Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::add, 0), MVT::i32);
295   return true;
296 }
297
298 bool ARMDAGToDAGISel::SelectAddrMode3Offset(SDValue Op, SDValue N,
299                                             SDValue &Offset, SDValue &Opc) {
300   unsigned Opcode = Op.getOpcode();
301   ISD::MemIndexedMode AM = (Opcode == ISD::LOAD)
302     ? cast<LoadSDNode>(Op)->getAddressingMode()
303     : cast<StoreSDNode>(Op)->getAddressingMode();
304   ARM_AM::AddrOpc AddSub = (AM == ISD::PRE_INC || AM == ISD::POST_INC)
305     ? ARM_AM::add : ARM_AM::sub;
306   if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N)) {
307     int Val = (int)C->getValue();
308     if (Val >= 0 && Val < 256) {
309       Offset = CurDAG->getRegister(0, MVT::i32);
310       Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(AddSub, Val), MVT::i32);
311       return true;
312     }
313   }
314
315   Offset = N;
316   Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(AddSub, 0), MVT::i32);
317   return true;
318 }
319
320
321 bool ARMDAGToDAGISel::SelectAddrMode5(SDValue Op, SDValue N,
322                                       SDValue &Base, SDValue &Offset) {
323   if (N.getOpcode() != ISD::ADD) {
324     Base = N;
325     if (N.getOpcode() == ISD::FrameIndex) {
326       int FI = cast<FrameIndexSDNode>(N)->getIndex();
327       Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy());
328     } else if (N.getOpcode() == ARMISD::Wrapper) {
329       Base = N.getOperand(0);
330     }
331     Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::add, 0),
332                                        MVT::i32);
333     return true;
334   }
335   
336   // If the RHS is +/- imm8, fold into addr mode.
337   if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
338     int RHSC = (int)RHS->getValue();
339     if ((RHSC & 3) == 0) {  // The constant is implicitly multiplied by 4.
340       RHSC >>= 2;
341       if ((RHSC >= 0 && RHSC < 256) ||
342           (RHSC < 0 && RHSC > -256)) { // note -256 itself isn't allowed.
343         Base = N.getOperand(0);
344         if (Base.getOpcode() == ISD::FrameIndex) {
345           int FI = cast<FrameIndexSDNode>(Base)->getIndex();
346           Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy());
347         }
348
349         ARM_AM::AddrOpc AddSub = ARM_AM::add;
350         if (RHSC < 0) {
351           AddSub = ARM_AM::sub;
352           RHSC = - RHSC;
353         }
354         Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(AddSub, RHSC),
355                                            MVT::i32);
356         return true;
357       }
358     }
359   }
360   
361   Base = N;
362   Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::add, 0),
363                                      MVT::i32);
364   return true;
365 }
366
367 bool ARMDAGToDAGISel::SelectAddrModePC(SDValue Op, SDValue N,
368                                         SDValue &Offset, SDValue &Label) {
369   if (N.getOpcode() == ARMISD::PIC_ADD && N.hasOneUse()) {
370     Offset = N.getOperand(0);
371     SDValue N1 = N.getOperand(1);
372     Label  = CurDAG->getTargetConstant(cast<ConstantSDNode>(N1)->getValue(),
373                                        MVT::i32);
374     return true;
375   }
376   return false;
377 }
378
379 bool ARMDAGToDAGISel::SelectThumbAddrModeRR(SDValue Op, SDValue N,
380                                             SDValue &Base, SDValue &Offset){
381   if (N.getOpcode() != ISD::ADD) {
382     Base = N;
383     // We must materialize a zero in a reg! Returning an constant here won't
384     // work since its node is -1 so it won't get added to the selection queue.
385     // Explicitly issue a tMOVri8 node!
386     Offset = SDValue(CurDAG->getTargetNode(ARM::tMOVi8, MVT::i32,
387                                     CurDAG->getTargetConstant(0, MVT::i32)), 0);
388     return true;
389   }
390
391   Base = N.getOperand(0);
392   Offset = N.getOperand(1);
393   return true;
394 }
395
396 bool
397 ARMDAGToDAGISel::SelectThumbAddrModeRI5(SDValue Op, SDValue N,
398                                         unsigned Scale, SDValue &Base,
399                                         SDValue &OffImm, SDValue &Offset) {
400   if (Scale == 4) {
401     SDValue TmpBase, TmpOffImm;
402     if (SelectThumbAddrModeSP(Op, N, TmpBase, TmpOffImm))
403       return false;  // We want to select tLDRspi / tSTRspi instead.
404     if (N.getOpcode() == ARMISD::Wrapper &&
405         N.getOperand(0).getOpcode() == ISD::TargetConstantPool)
406       return false;  // We want to select tLDRpci instead.
407   }
408
409   if (N.getOpcode() != ISD::ADD) {
410     Base = (N.getOpcode() == ARMISD::Wrapper) ? N.getOperand(0) : N;
411     Offset = CurDAG->getRegister(0, MVT::i32);
412     OffImm = CurDAG->getTargetConstant(0, MVT::i32);
413     return true;
414   }
415
416   // Thumb does not have [sp, r] address mode.
417   RegisterSDNode *LHSR = dyn_cast<RegisterSDNode>(N.getOperand(0));
418   RegisterSDNode *RHSR = dyn_cast<RegisterSDNode>(N.getOperand(1));
419   if ((LHSR && LHSR->getReg() == ARM::SP) ||
420       (RHSR && RHSR->getReg() == ARM::SP)) {
421     Base = N;
422     Offset = CurDAG->getRegister(0, MVT::i32);
423     OffImm = CurDAG->getTargetConstant(0, MVT::i32);
424     return true;
425   }
426
427   // If the RHS is + imm5 * scale, fold into addr mode.
428   if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
429     int RHSC = (int)RHS->getValue();
430     if ((RHSC & (Scale-1)) == 0) {  // The constant is implicitly multiplied.
431       RHSC /= Scale;
432       if (RHSC >= 0 && RHSC < 32) {
433         Base = N.getOperand(0);
434         Offset = CurDAG->getRegister(0, MVT::i32);
435         OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32);
436         return true;
437       }
438     }
439   }
440
441   Base = N.getOperand(0);
442   Offset = N.getOperand(1);
443   OffImm = CurDAG->getTargetConstant(0, MVT::i32);
444   return true;
445 }
446
447 bool ARMDAGToDAGISel::SelectThumbAddrModeS1(SDValue Op, SDValue N,
448                                             SDValue &Base, SDValue &OffImm,
449                                             SDValue &Offset) {
450   return SelectThumbAddrModeRI5(Op, N, 1, Base, OffImm, Offset);
451 }
452
453 bool ARMDAGToDAGISel::SelectThumbAddrModeS2(SDValue Op, SDValue N,
454                                             SDValue &Base, SDValue &OffImm,
455                                             SDValue &Offset) {
456   return SelectThumbAddrModeRI5(Op, N, 2, Base, OffImm, Offset);
457 }
458
459 bool ARMDAGToDAGISel::SelectThumbAddrModeS4(SDValue Op, SDValue N,
460                                             SDValue &Base, SDValue &OffImm,
461                                             SDValue &Offset) {
462   return SelectThumbAddrModeRI5(Op, N, 4, Base, OffImm, Offset);
463 }
464
465 bool ARMDAGToDAGISel::SelectThumbAddrModeSP(SDValue Op, SDValue N,
466                                            SDValue &Base, SDValue &OffImm) {
467   if (N.getOpcode() == ISD::FrameIndex) {
468     int FI = cast<FrameIndexSDNode>(N)->getIndex();
469     Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy());
470     OffImm = CurDAG->getTargetConstant(0, MVT::i32);
471     return true;
472   }
473
474   if (N.getOpcode() != ISD::ADD)
475     return false;
476
477   RegisterSDNode *LHSR = dyn_cast<RegisterSDNode>(N.getOperand(0));
478   if (N.getOperand(0).getOpcode() == ISD::FrameIndex ||
479       (LHSR && LHSR->getReg() == ARM::SP)) {
480     // If the RHS is + imm8 * scale, fold into addr mode.
481     if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
482       int RHSC = (int)RHS->getValue();
483       if ((RHSC & 3) == 0) {  // The constant is implicitly multiplied.
484         RHSC >>= 2;
485         if (RHSC >= 0 && RHSC < 256) {
486           Base = N.getOperand(0);
487           if (Base.getOpcode() == ISD::FrameIndex) {
488             int FI = cast<FrameIndexSDNode>(Base)->getIndex();
489             Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy());
490           }
491           OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32);
492           return true;
493         }
494       }
495     }
496   }
497   
498   return false;
499 }
500
501 bool ARMDAGToDAGISel::SelectShifterOperandReg(SDValue Op,
502                                               SDValue N, 
503                                               SDValue &BaseReg,
504                                               SDValue &ShReg,
505                                               SDValue &Opc) {
506   ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N);
507
508   // Don't match base register only case. That is matched to a separate
509   // lower complexity pattern with explicit register operand.
510   if (ShOpcVal == ARM_AM::no_shift) return false;
511   
512   BaseReg = N.getOperand(0);
513   unsigned ShImmVal = 0;
514   if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
515     ShReg = CurDAG->getRegister(0, MVT::i32);
516     ShImmVal = RHS->getValue() & 31;
517   } else {
518     ShReg = N.getOperand(1);
519   }
520   Opc = CurDAG->getTargetConstant(ARM_AM::getSORegOpc(ShOpcVal, ShImmVal),
521                                   MVT::i32);
522   return true;
523 }
524
525 /// getAL - Returns a ARMCC::AL immediate node.
526 static inline SDValue getAL(SelectionDAG *CurDAG) {
527   return CurDAG->getTargetConstant((uint64_t)ARMCC::AL, MVT::i32);
528 }
529
530
531 SDNode *ARMDAGToDAGISel::Select(SDValue Op) {
532   SDNode *N = Op.Val;
533
534   if (N->isMachineOpcode())
535     return NULL;   // Already selected.
536
537   switch (N->getOpcode()) {
538   default: break;
539   case ISD::Constant: {
540     unsigned Val = cast<ConstantSDNode>(N)->getValue();
541     bool UseCP = true;
542     if (Subtarget->isThumb())
543       UseCP = (Val > 255 &&                          // MOV
544                ~Val > 255 &&                         // MOV + MVN
545                !ARM_AM::isThumbImmShiftedVal(Val));  // MOV + LSL
546     else
547       UseCP = (ARM_AM::getSOImmVal(Val) == -1 &&     // MOV
548                ARM_AM::getSOImmVal(~Val) == -1 &&    // MVN
549                !ARM_AM::isSOImmTwoPartVal(Val));     // two instrs.
550     if (UseCP) {
551       SDValue CPIdx =
552         CurDAG->getTargetConstantPool(ConstantInt::get(Type::Int32Ty, Val),
553                                       TLI.getPointerTy());
554
555       SDNode *ResNode;
556       if (Subtarget->isThumb())
557         ResNode = CurDAG->getTargetNode(ARM::tLDRcp, MVT::i32, MVT::Other,
558                                         CPIdx, CurDAG->getEntryNode());
559       else {
560         SDValue Ops[] = {
561           CPIdx, 
562           CurDAG->getRegister(0, MVT::i32),
563           CurDAG->getTargetConstant(0, MVT::i32),
564           getAL(CurDAG),
565           CurDAG->getRegister(0, MVT::i32),
566           CurDAG->getEntryNode()
567         };
568         ResNode=CurDAG->getTargetNode(ARM::LDRcp, MVT::i32, MVT::Other, Ops, 6);
569       }
570       ReplaceUses(Op, SDValue(ResNode, 0));
571       return NULL;
572     }
573       
574     // Other cases are autogenerated.
575     break;
576   }
577   case ISD::FrameIndex: {
578     // Selects to ADDri FI, 0 which in turn will become ADDri SP, imm.
579     int FI = cast<FrameIndexSDNode>(N)->getIndex();
580     SDValue TFI = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy());
581     if (Subtarget->isThumb())
582       return CurDAG->SelectNodeTo(N, ARM::tADDrSPi, MVT::i32, TFI,
583                                   CurDAG->getTargetConstant(0, MVT::i32));
584     else {
585       SDValue Ops[] = { TFI, CurDAG->getTargetConstant(0, MVT::i32),
586                           getAL(CurDAG), CurDAG->getRegister(0, MVT::i32),
587                           CurDAG->getRegister(0, MVT::i32) };
588       return CurDAG->SelectNodeTo(N, ARM::ADDri, MVT::i32, Ops, 5);
589     }
590   }
591   case ISD::ADD: {
592     // Select add sp, c to tADDhirr.
593     SDValue N0 = Op.getOperand(0);
594     SDValue N1 = Op.getOperand(1);
595     RegisterSDNode *LHSR = dyn_cast<RegisterSDNode>(Op.getOperand(0));
596     RegisterSDNode *RHSR = dyn_cast<RegisterSDNode>(Op.getOperand(1));
597     if (LHSR && LHSR->getReg() == ARM::SP) {
598       std::swap(N0, N1);
599       std::swap(LHSR, RHSR);
600     }
601     if (RHSR && RHSR->getReg() == ARM::SP) {
602       AddToISelQueue(N0);
603       AddToISelQueue(N1);
604       return CurDAG->SelectNodeTo(N, ARM::tADDhirr, Op.getValueType(), N0, N1);
605     }
606     break;
607   }
608   case ISD::MUL:
609     if (Subtarget->isThumb())
610       break;
611     if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
612       unsigned RHSV = C->getValue();
613       if (!RHSV) break;
614       if (isPowerOf2_32(RHSV-1)) {  // 2^n+1?
615         SDValue V = Op.getOperand(0);
616         AddToISelQueue(V);
617         unsigned ShImm = ARM_AM::getSORegOpc(ARM_AM::lsl, Log2_32(RHSV-1));
618         SDValue Ops[] = { V, V, CurDAG->getRegister(0, MVT::i32),
619                             CurDAG->getTargetConstant(ShImm, MVT::i32),
620                             getAL(CurDAG), CurDAG->getRegister(0, MVT::i32),
621                             CurDAG->getRegister(0, MVT::i32) };
622         return CurDAG->SelectNodeTo(N, ARM::ADDrs, MVT::i32, Ops, 7);
623       }
624       if (isPowerOf2_32(RHSV+1)) {  // 2^n-1?
625         SDValue V = Op.getOperand(0);
626         AddToISelQueue(V);
627         unsigned ShImm = ARM_AM::getSORegOpc(ARM_AM::lsl, Log2_32(RHSV+1));
628         SDValue Ops[] = { V, V, CurDAG->getRegister(0, MVT::i32),
629                             CurDAG->getTargetConstant(ShImm, MVT::i32),
630                             getAL(CurDAG), CurDAG->getRegister(0, MVT::i32),
631                             CurDAG->getRegister(0, MVT::i32) };
632         return CurDAG->SelectNodeTo(N, ARM::RSBrs, MVT::i32, Ops, 7);
633       }
634     }
635     break;
636   case ARMISD::FMRRD:
637     AddToISelQueue(Op.getOperand(0));
638     return CurDAG->getTargetNode(ARM::FMRRD, MVT::i32, MVT::i32,
639                                  Op.getOperand(0), getAL(CurDAG),
640                                  CurDAG->getRegister(0, MVT::i32));
641   case ISD::UMUL_LOHI: {
642     AddToISelQueue(Op.getOperand(0));
643     AddToISelQueue(Op.getOperand(1));
644     SDValue Ops[] = { Op.getOperand(0), Op.getOperand(1),
645                         getAL(CurDAG), CurDAG->getRegister(0, MVT::i32),
646                         CurDAG->getRegister(0, MVT::i32) };
647     return CurDAG->getTargetNode(ARM::UMULL, MVT::i32, MVT::i32, Ops, 5);
648   }
649   case ISD::SMUL_LOHI: {
650     AddToISelQueue(Op.getOperand(0));
651     AddToISelQueue(Op.getOperand(1));
652     SDValue Ops[] = { Op.getOperand(0), Op.getOperand(1),
653                         getAL(CurDAG), CurDAG->getRegister(0, MVT::i32),
654                         CurDAG->getRegister(0, MVT::i32) };
655     return CurDAG->getTargetNode(ARM::SMULL, MVT::i32, MVT::i32, Ops, 5);
656   }
657   case ISD::LOAD: {
658     LoadSDNode *LD = cast<LoadSDNode>(Op);
659     ISD::MemIndexedMode AM = LD->getAddressingMode();
660     MVT LoadedVT = LD->getMemoryVT();
661     if (AM != ISD::UNINDEXED) {
662       SDValue Offset, AMOpc;
663       bool isPre = (AM == ISD::PRE_INC) || (AM == ISD::PRE_DEC);
664       unsigned Opcode = 0;
665       bool Match = false;
666       if (LoadedVT == MVT::i32 &&
667           SelectAddrMode2Offset(Op, LD->getOffset(), Offset, AMOpc)) {
668         Opcode = isPre ? ARM::LDR_PRE : ARM::LDR_POST;
669         Match = true;
670       } else if (LoadedVT == MVT::i16 &&
671                  SelectAddrMode3Offset(Op, LD->getOffset(), Offset, AMOpc)) {
672         Match = true;
673         Opcode = (LD->getExtensionType() == ISD::SEXTLOAD)
674           ? (isPre ? ARM::LDRSH_PRE : ARM::LDRSH_POST)
675           : (isPre ? ARM::LDRH_PRE : ARM::LDRH_POST);
676       } else if (LoadedVT == MVT::i8 || LoadedVT == MVT::i1) {
677         if (LD->getExtensionType() == ISD::SEXTLOAD) {
678           if (SelectAddrMode3Offset(Op, LD->getOffset(), Offset, AMOpc)) {
679             Match = true;
680             Opcode = isPre ? ARM::LDRSB_PRE : ARM::LDRSB_POST;
681           }
682         } else {
683           if (SelectAddrMode2Offset(Op, LD->getOffset(), Offset, AMOpc)) {
684             Match = true;
685             Opcode = isPre ? ARM::LDRB_PRE : ARM::LDRB_POST;
686           }
687         }
688       }
689
690       if (Match) {
691         SDValue Chain = LD->getChain();
692         SDValue Base = LD->getBasePtr();
693         AddToISelQueue(Chain);
694         AddToISelQueue(Base);
695         AddToISelQueue(Offset);
696         SDValue Ops[]= { Base, Offset, AMOpc, getAL(CurDAG),
697                            CurDAG->getRegister(0, MVT::i32), Chain };
698         return CurDAG->getTargetNode(Opcode, MVT::i32, MVT::i32,
699                                      MVT::Other, Ops, 6);
700       }
701     }
702     // Other cases are autogenerated.
703     break;
704   }
705   case ARMISD::BRCOND: {
706     // Pattern: (ARMbrcond:void (bb:Other):$dst, (imm:i32):$cc)
707     // Emits: (Bcc:void (bb:Other):$dst, (imm:i32):$cc)
708     // Pattern complexity = 6  cost = 1  size = 0
709
710     // Pattern: (ARMbrcond:void (bb:Other):$dst, (imm:i32):$cc)
711     // Emits: (tBcc:void (bb:Other):$dst, (imm:i32):$cc)
712     // Pattern complexity = 6  cost = 1  size = 0
713
714     unsigned Opc = Subtarget->isThumb() ? ARM::tBcc : ARM::Bcc;
715     SDValue Chain = Op.getOperand(0);
716     SDValue N1 = Op.getOperand(1);
717     SDValue N2 = Op.getOperand(2);
718     SDValue N3 = Op.getOperand(3);
719     SDValue InFlag = Op.getOperand(4);
720     assert(N1.getOpcode() == ISD::BasicBlock);
721     assert(N2.getOpcode() == ISD::Constant);
722     assert(N3.getOpcode() == ISD::Register);
723
724     AddToISelQueue(Chain);
725     AddToISelQueue(N1);
726     AddToISelQueue(InFlag);
727     SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned)
728                                cast<ConstantSDNode>(N2)->getValue()), MVT::i32);
729     SDValue Ops[] = { N1, Tmp2, N3, Chain, InFlag };
730     SDNode *ResNode = CurDAG->getTargetNode(Opc, MVT::Other, MVT::Flag, Ops, 5);
731     Chain = SDValue(ResNode, 0);
732     if (Op.Val->getNumValues() == 2) {
733       InFlag = SDValue(ResNode, 1);
734       ReplaceUses(SDValue(Op.Val, 1), InFlag);
735     }
736     ReplaceUses(SDValue(Op.Val, 0), SDValue(Chain.Val, Chain.ResNo));
737     return NULL;
738   }
739   case ARMISD::CMOV: {
740     bool isThumb = Subtarget->isThumb();
741     MVT VT = Op.getValueType();
742     SDValue N0 = Op.getOperand(0);
743     SDValue N1 = Op.getOperand(1);
744     SDValue N2 = Op.getOperand(2);
745     SDValue N3 = Op.getOperand(3);
746     SDValue InFlag = Op.getOperand(4);
747     assert(N2.getOpcode() == ISD::Constant);
748     assert(N3.getOpcode() == ISD::Register);
749
750     // Pattern: (ARMcmov:i32 GPR:i32:$false, so_reg:i32:$true, (imm:i32):$cc)
751     // Emits: (MOVCCs:i32 GPR:i32:$false, so_reg:i32:$true, (imm:i32):$cc)
752     // Pattern complexity = 18  cost = 1  size = 0
753     SDValue CPTmp0;
754     SDValue CPTmp1;
755     SDValue CPTmp2;
756     if (!isThumb && VT == MVT::i32 &&
757         SelectShifterOperandReg(Op, N1, CPTmp0, CPTmp1, CPTmp2)) {
758       AddToISelQueue(N0);
759       AddToISelQueue(CPTmp0);
760       AddToISelQueue(CPTmp1);
761       AddToISelQueue(CPTmp2);
762       AddToISelQueue(InFlag);
763       SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned)
764                                cast<ConstantSDNode>(N2)->getValue()), MVT::i32);
765       SDValue Ops[] = { N0, CPTmp0, CPTmp1, CPTmp2, Tmp2, N3, InFlag };
766       return CurDAG->SelectNodeTo(Op.Val, ARM::MOVCCs, MVT::i32, Ops, 7);
767     }
768
769     // Pattern: (ARMcmov:i32 GPR:i32:$false,
770     //             (imm:i32)<<P:Predicate_so_imm>><<X:so_imm_XFORM>>:$true,
771     //             (imm:i32):$cc)
772     // Emits: (MOVCCi:i32 GPR:i32:$false,
773     //           (so_imm_XFORM:i32 (imm:i32):$true), (imm:i32):$cc)
774     // Pattern complexity = 10  cost = 1  size = 0
775     if (VT == MVT::i32 &&
776         N3.getOpcode() == ISD::Constant &&
777         Predicate_so_imm(N3.Val)) {
778       AddToISelQueue(N0);
779       AddToISelQueue(InFlag);
780       SDValue Tmp1 = CurDAG->getTargetConstant(((unsigned)
781                                cast<ConstantSDNode>(N1)->getValue()), MVT::i32);
782       Tmp1 = Transform_so_imm_XFORM(Tmp1.Val);
783       SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned)
784                                cast<ConstantSDNode>(N2)->getValue()), MVT::i32);
785       SDValue Ops[] = { N0, Tmp1, Tmp2, N3, InFlag };
786       return CurDAG->SelectNodeTo(Op.Val, ARM::MOVCCi, MVT::i32, Ops, 5);
787     }
788
789     // Pattern: (ARMcmov:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc)
790     // Emits: (MOVCCr:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc)
791     // Pattern complexity = 6  cost = 1  size = 0
792     //
793     // Pattern: (ARMcmov:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc)
794     // Emits: (tMOVCCr:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc)
795     // Pattern complexity = 6  cost = 11  size = 0
796     //
797     // Also FCPYScc and FCPYDcc.
798     AddToISelQueue(N0);
799     AddToISelQueue(N1);
800     AddToISelQueue(InFlag);
801     SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned)
802                                cast<ConstantSDNode>(N2)->getValue()), MVT::i32);
803     SDValue Ops[] = { N0, N1, Tmp2, N3, InFlag };
804     unsigned Opc = 0;
805     switch (VT.getSimpleVT()) {
806     default: assert(false && "Illegal conditional move type!");
807       break;
808     case MVT::i32:
809       Opc = isThumb ? ARM::tMOVCCr : ARM::MOVCCr;
810       break;
811     case MVT::f32:
812       Opc = ARM::FCPYScc;
813       break;
814     case MVT::f64:
815       Opc = ARM::FCPYDcc;
816       break; 
817     }
818     return CurDAG->SelectNodeTo(Op.Val, Opc, VT, Ops, 5);
819   }
820   case ARMISD::CNEG: {
821     MVT VT = Op.getValueType();
822     SDValue N0 = Op.getOperand(0);
823     SDValue N1 = Op.getOperand(1);
824     SDValue N2 = Op.getOperand(2);
825     SDValue N3 = Op.getOperand(3);
826     SDValue InFlag = Op.getOperand(4);
827     assert(N2.getOpcode() == ISD::Constant);
828     assert(N3.getOpcode() == ISD::Register);
829
830     AddToISelQueue(N0);
831     AddToISelQueue(N1);
832     AddToISelQueue(InFlag);
833     SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned)
834                                cast<ConstantSDNode>(N2)->getValue()), MVT::i32);
835     SDValue Ops[] = { N0, N1, Tmp2, N3, InFlag };
836     unsigned Opc = 0;
837     switch (VT.getSimpleVT()) {
838     default: assert(false && "Illegal conditional move type!");
839       break;
840     case MVT::f32:
841       Opc = ARM::FNEGScc;
842       break;
843     case MVT::f64:
844       Opc = ARM::FNEGDcc;
845       break; 
846     }
847     return CurDAG->SelectNodeTo(Op.Val, Opc, VT, Ops, 5);
848   }
849   }
850   return SelectCode(Op);
851 }
852
853 /// createARMISelDag - This pass converts a legalized DAG into a
854 /// ARM-specific DAG, ready for instruction scheduling.
855 ///
856 FunctionPass *llvm::createARMISelDag(ARMTargetMachine &TM) {
857   return new ARMDAGToDAGISel(TM);
858 }