Sink InstructionSelect() out of each target into SDISel, and rename it
[oota-llvm.git] / lib / Target / MSP430 / MSP430ISelDAGToDAG.cpp
1 //===-- MSP430ISelDAGToDAG.cpp - A dag to dag inst selector for MSP430 ----===//
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 MSP430 target.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "MSP430.h"
15 #include "MSP430ISelLowering.h"
16 #include "MSP430TargetMachine.h"
17 #include "llvm/DerivedTypes.h"
18 #include "llvm/Function.h"
19 #include "llvm/Intrinsics.h"
20 #include "llvm/CallingConv.h"
21 #include "llvm/Constants.h"
22 #include "llvm/CodeGen/MachineFrameInfo.h"
23 #include "llvm/CodeGen/MachineFunction.h"
24 #include "llvm/CodeGen/MachineInstrBuilder.h"
25 #include "llvm/CodeGen/MachineRegisterInfo.h"
26 #include "llvm/CodeGen/SelectionDAG.h"
27 #include "llvm/CodeGen/SelectionDAGISel.h"
28 #include "llvm/Target/TargetLowering.h"
29 #include "llvm/Support/Compiler.h"
30 #include "llvm/Support/Debug.h"
31 #include "llvm/Support/ErrorHandling.h"
32 #include "llvm/Support/raw_ostream.h"
33 #include "llvm/ADT/Statistic.h"
34
35 using namespace llvm;
36
37 STATISTIC(NumLoadMoved, "Number of loads moved below TokenFactor");
38
39
40 namespace {
41   struct MSP430ISelAddressMode {
42     enum {
43       RegBase,
44       FrameIndexBase
45     } BaseType;
46
47     struct {            // This is really a union, discriminated by BaseType!
48       SDValue Reg;
49       int FrameIndex;
50     } Base;
51
52     int16_t Disp;
53     GlobalValue *GV;
54     Constant *CP;
55     BlockAddress *BlockAddr;
56     const char *ES;
57     int JT;
58     unsigned Align;    // CP alignment.
59
60     MSP430ISelAddressMode()
61       : BaseType(RegBase), Disp(0), GV(0), CP(0), BlockAddr(0),
62         ES(0), JT(-1), Align(0) {
63     }
64
65     bool hasSymbolicDisplacement() const {
66       return GV != 0 || CP != 0 || ES != 0 || JT != -1;
67     }
68
69     bool hasBaseReg() const {
70       return Base.Reg.getNode() != 0;
71     }
72
73     void setBaseReg(SDValue Reg) {
74       BaseType = RegBase;
75       Base.Reg = Reg;
76     }
77
78     void dump() {
79       errs() << "MSP430ISelAddressMode " << this << '\n';
80       if (BaseType == RegBase && Base.Reg.getNode() != 0) {
81         errs() << "Base.Reg ";
82         Base.Reg.getNode()->dump();
83       } else if (BaseType == FrameIndexBase) {
84         errs() << " Base.FrameIndex " << Base.FrameIndex << '\n';
85       }
86       errs() << " Disp " << Disp << '\n';
87       if (GV) {
88         errs() << "GV ";
89         GV->dump();
90       } else if (CP) {
91         errs() << " CP ";
92         CP->dump();
93         errs() << " Align" << Align << '\n';
94       } else if (ES) {
95         errs() << "ES ";
96         errs() << ES << '\n';
97       } else if (JT != -1)
98         errs() << " JT" << JT << " Align" << Align << '\n';
99     }
100   };
101 }
102
103 /// MSP430DAGToDAGISel - MSP430 specific code to select MSP430 machine
104 /// instructions for SelectionDAG operations.
105 ///
106 namespace {
107   class MSP430DAGToDAGISel : public SelectionDAGISel {
108     MSP430TargetLowering &Lowering;
109     const MSP430Subtarget &Subtarget;
110
111   public:
112     MSP430DAGToDAGISel(MSP430TargetMachine &TM, CodeGenOpt::Level OptLevel)
113       : SelectionDAGISel(TM, OptLevel),
114         Lowering(*TM.getTargetLowering()),
115         Subtarget(*TM.getSubtargetImpl()) { }
116
117     virtual void PreprocessISelDAG();
118     virtual void PostprocessISelDAG();
119
120     virtual const char *getPassName() const {
121       return "MSP430 DAG->DAG Pattern Instruction Selection";
122     }
123
124     bool MatchAddress(SDValue N, MSP430ISelAddressMode &AM);
125     bool MatchWrapper(SDValue N, MSP430ISelAddressMode &AM);
126     bool MatchAddressBase(SDValue N, MSP430ISelAddressMode &AM);
127
128     bool IsLegalToFold(SDValue N, SDNode *U, SDNode *Root) const;
129
130     virtual bool
131     SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
132                                  std::vector<SDValue> &OutOps);
133
134     // Include the pieces autogenerated from the target description.
135   #include "MSP430GenDAGISel.inc"
136
137   private:
138     DenseMap<SDNode*, SDNode*> RMWStores;
139     void PreprocessForRMW();
140     SDNode *Select(SDNode *N);
141     SDNode *SelectIndexedLoad(SDNode *Op);
142     SDNode *SelectIndexedBinOp(SDNode *Op, SDValue N1, SDValue N2,
143                                unsigned Opc8, unsigned Opc16);
144
145     bool SelectAddr(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Disp);
146   };
147 }  // end anonymous namespace
148
149 /// createMSP430ISelDag - This pass converts a legalized DAG into a
150 /// MSP430-specific DAG, ready for instruction scheduling.
151 ///
152 FunctionPass *llvm::createMSP430ISelDag(MSP430TargetMachine &TM,
153                                         CodeGenOpt::Level OptLevel) {
154   return new MSP430DAGToDAGISel(TM, OptLevel);
155 }
156
157
158 /// MatchWrapper - Try to match MSP430ISD::Wrapper node into an addressing mode.
159 /// These wrap things that will resolve down into a symbol reference.  If no
160 /// match is possible, this returns true, otherwise it returns false.
161 bool MSP430DAGToDAGISel::MatchWrapper(SDValue N, MSP430ISelAddressMode &AM) {
162   // If the addressing mode already has a symbol as the displacement, we can
163   // never match another symbol.
164   if (AM.hasSymbolicDisplacement())
165     return true;
166
167   SDValue N0 = N.getOperand(0);
168
169   if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(N0)) {
170     AM.GV = G->getGlobal();
171     AM.Disp += G->getOffset();
172     //AM.SymbolFlags = G->getTargetFlags();
173   } else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(N0)) {
174     AM.CP = CP->getConstVal();
175     AM.Align = CP->getAlignment();
176     AM.Disp += CP->getOffset();
177     //AM.SymbolFlags = CP->getTargetFlags();
178   } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(N0)) {
179     AM.ES = S->getSymbol();
180     //AM.SymbolFlags = S->getTargetFlags();
181   } else if (JumpTableSDNode *J = dyn_cast<JumpTableSDNode>(N0)) {
182     AM.JT = J->getIndex();
183     //AM.SymbolFlags = J->getTargetFlags();
184   } else {
185     AM.BlockAddr = cast<BlockAddressSDNode>(N0)->getBlockAddress();
186     //AM.SymbolFlags = cast<BlockAddressSDNode>(N0)->getTargetFlags();
187   }
188   return false;
189 }
190
191 /// MatchAddressBase - Helper for MatchAddress. Add the specified node to the
192 /// specified addressing mode without any further recursion.
193 bool MSP430DAGToDAGISel::MatchAddressBase(SDValue N, MSP430ISelAddressMode &AM) {
194   // Is the base register already occupied?
195   if (AM.BaseType != MSP430ISelAddressMode::RegBase || AM.Base.Reg.getNode()) {
196     // If so, we cannot select it.
197     return true;
198   }
199
200   // Default, generate it as a register.
201   AM.BaseType = MSP430ISelAddressMode::RegBase;
202   AM.Base.Reg = N;
203   return false;
204 }
205
206 bool MSP430DAGToDAGISel::MatchAddress(SDValue N, MSP430ISelAddressMode &AM) {
207   DEBUG({
208       errs() << "MatchAddress: ";
209       AM.dump();
210     });
211
212   switch (N.getOpcode()) {
213   default: break;
214   case ISD::Constant: {
215     uint64_t Val = cast<ConstantSDNode>(N)->getSExtValue();
216     AM.Disp += Val;
217     return false;
218   }
219
220   case MSP430ISD::Wrapper:
221     if (!MatchWrapper(N, AM))
222       return false;
223     break;
224
225   case ISD::FrameIndex:
226     if (AM.BaseType == MSP430ISelAddressMode::RegBase
227         && AM.Base.Reg.getNode() == 0) {
228       AM.BaseType = MSP430ISelAddressMode::FrameIndexBase;
229       AM.Base.FrameIndex = cast<FrameIndexSDNode>(N)->getIndex();
230       return false;
231     }
232     break;
233
234   case ISD::ADD: {
235     MSP430ISelAddressMode Backup = AM;
236     if (!MatchAddress(N.getNode()->getOperand(0), AM) &&
237         !MatchAddress(N.getNode()->getOperand(1), AM))
238       return false;
239     AM = Backup;
240     if (!MatchAddress(N.getNode()->getOperand(1), AM) &&
241         !MatchAddress(N.getNode()->getOperand(0), AM))
242       return false;
243     AM = Backup;
244
245     break;
246   }
247
248   case ISD::OR:
249     // Handle "X | C" as "X + C" iff X is known to have C bits clear.
250     if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
251       MSP430ISelAddressMode Backup = AM;
252       uint64_t Offset = CN->getSExtValue();
253       // Start with the LHS as an addr mode.
254       if (!MatchAddress(N.getOperand(0), AM) &&
255           // Address could not have picked a GV address for the displacement.
256           AM.GV == NULL &&
257           // Check to see if the LHS & C is zero.
258           CurDAG->MaskedValueIsZero(N.getOperand(0), CN->getAPIntValue())) {
259         AM.Disp += Offset;
260         return false;
261       }
262       AM = Backup;
263     }
264     break;
265   }
266
267   return MatchAddressBase(N, AM);
268 }
269
270 /// SelectAddr - returns true if it is able pattern match an addressing mode.
271 /// It returns the operands which make up the maximal addressing mode it can
272 /// match by reference.
273 bool MSP430DAGToDAGISel::SelectAddr(SDNode *Op, SDValue N,
274                                     SDValue &Base, SDValue &Disp) {
275   MSP430ISelAddressMode AM;
276
277   if (MatchAddress(N, AM))
278     return false;
279
280   EVT VT = N.getValueType();
281   if (AM.BaseType == MSP430ISelAddressMode::RegBase) {
282     if (!AM.Base.Reg.getNode())
283       AM.Base.Reg = CurDAG->getRegister(0, VT);
284   }
285
286   Base  = (AM.BaseType == MSP430ISelAddressMode::FrameIndexBase) ?
287     CurDAG->getTargetFrameIndex(AM.Base.FrameIndex, TLI.getPointerTy()) :
288     AM.Base.Reg;
289
290   if (AM.GV)
291     Disp = CurDAG->getTargetGlobalAddress(AM.GV, MVT::i16, AM.Disp,
292                                           0/*AM.SymbolFlags*/);
293   else if (AM.CP)
294     Disp = CurDAG->getTargetConstantPool(AM.CP, MVT::i16,
295                                          AM.Align, AM.Disp, 0/*AM.SymbolFlags*/);
296   else if (AM.ES)
297     Disp = CurDAG->getTargetExternalSymbol(AM.ES, MVT::i16, 0/*AM.SymbolFlags*/);
298   else if (AM.JT != -1)
299     Disp = CurDAG->getTargetJumpTable(AM.JT, MVT::i16, 0/*AM.SymbolFlags*/);
300   else if (AM.BlockAddr)
301     Disp = CurDAG->getBlockAddress(AM.BlockAddr, MVT::i32,
302                                    true, 0/*AM.SymbolFlags*/);
303   else
304     Disp = CurDAG->getTargetConstant(AM.Disp, MVT::i16);
305
306   return true;
307 }
308
309 bool MSP430DAGToDAGISel::
310 SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
311                              std::vector<SDValue> &OutOps) {
312   SDValue Op0, Op1;
313   switch (ConstraintCode) {
314   default: return true;
315   case 'm':   // memory
316     if (!SelectAddr(Op.getNode(), Op, Op0, Op1))
317       return true;
318     break;
319   }
320
321   OutOps.push_back(Op0);
322   OutOps.push_back(Op1);
323   return false;
324 }
325
326 bool MSP430DAGToDAGISel::IsLegalToFold(SDValue N, SDNode *U,
327                                        SDNode *Root) const {
328   if (OptLevel == CodeGenOpt::None) return false;
329
330   /// RMW preprocessing creates the following code:
331   ///         [Load1]
332   ///         ^     ^
333   ///        /      |
334   ///       /       |
335   ///       [Load2] |
336   ///       ^    ^  |
337   ///       |    |  |
338   ///       |     \-|
339   ///       |       |
340   ///       |     [Op]
341   ///       |       ^
342   ///       |       |
343   ///       \      /
344   ///        \    /
345   ///       [Store]
346   ///
347   /// The path Store => Load2 => Load1 is via chain. Note that in general it is
348   /// not allowed to fold Load1 into Op (and Store) since it will creates a
349   /// cycle. However, this is perfectly legal for the loads moved below the
350   /// TokenFactor by PreprocessForRMW. Query the map Store => Load1 (created
351   /// during preprocessing) to determine whether it's legal to introduce such
352   /// "cycle" for a moment.
353   DenseMap<SDNode*, SDNode*>::const_iterator I = RMWStores.find(Root);
354   if (I != RMWStores.end() && I->second == N.getNode())
355     return true;
356
357   // Proceed to 'generic' cycle finder code
358   return SelectionDAGISel::IsLegalToFold(N, U, Root);
359 }
360
361
362 /// MoveBelowTokenFactor - Replace TokenFactor operand with load's chain operand
363 /// and move load below the TokenFactor. Replace store's chain operand with
364 /// load's chain result.
365 static void MoveBelowTokenFactor(SelectionDAG *CurDAG, SDValue Load,
366                                  SDValue Store, SDValue TF) {
367   SmallVector<SDValue, 4> Ops;
368   for (unsigned i = 0, e = TF.getNode()->getNumOperands(); i != e; ++i)
369     if (Load.getNode() == TF.getOperand(i).getNode())
370       Ops.push_back(Load.getOperand(0));
371     else
372       Ops.push_back(TF.getOperand(i));
373   SDValue NewTF = CurDAG->UpdateNodeOperands(TF, &Ops[0], Ops.size());
374   SDValue NewLoad = CurDAG->UpdateNodeOperands(Load, NewTF,
375                                                Load.getOperand(1),
376                                                Load.getOperand(2));
377   CurDAG->UpdateNodeOperands(Store, NewLoad.getValue(1), Store.getOperand(1),
378                              Store.getOperand(2), Store.getOperand(3));
379 }
380
381 /// MoveBelowTokenFactor2 - Replace TokenFactor operand with load's chain operand
382 /// and move load below the TokenFactor. Replace store's chain operand with
383 /// load's chain result. This a version which sinks two loads below token factor.
384 /// Look into PreprocessForRMW comments for explanation of transform.
385 static void MoveBelowTokenFactor2(SelectionDAG *CurDAG,
386                                   SDValue Load1, SDValue Load2,
387                                   SDValue Store, SDValue TF) {
388   SmallVector<SDValue, 4> Ops;
389   for (unsigned i = 0, e = TF.getNode()->getNumOperands(); i != e; ++i) {
390     SDNode* N = TF.getOperand(i).getNode();
391     if (Load2.getNode() == N)
392       Ops.push_back(Load2.getOperand(0));
393     else if (Load1.getNode() != N)
394       Ops.push_back(TF.getOperand(i));
395   }
396
397   SDValue NewTF = SDValue(CurDAG->MorphNodeTo(TF.getNode(),
398                                   TF.getOpcode(),
399                                   TF.getNode()->getVTList(),
400                                   &Ops[0], Ops.size()), TF.getResNo());
401   SDValue NewLoad2 = CurDAG->UpdateNodeOperands(Load2, NewTF,
402                                                 Load2.getOperand(1),
403                                                 Load2.getOperand(2));
404
405   SDValue NewLoad1 = CurDAG->UpdateNodeOperands(Load1, NewLoad2.getValue(1),
406                                                 Load1.getOperand(1),
407                                                 Load1.getOperand(2));
408
409   CurDAG->UpdateNodeOperands(Store,
410                              NewLoad1.getValue(1),
411                              Store.getOperand(1),
412                              Store.getOperand(2), Store.getOperand(3));
413 }
414
415 /// isAllowedToSink - return true if N a load which can be moved below token
416 /// factor. Basically, the load should be non-volatile and has single use.
417 static bool isLoadAllowedToSink(SDValue N, SDValue Chain) {
418   if (N.getOpcode() == ISD::BIT_CONVERT)
419     N = N.getOperand(0);
420
421   LoadSDNode *LD = dyn_cast<LoadSDNode>(N);
422   if (!LD || LD->isVolatile())
423     return false;
424   if (LD->getAddressingMode() != ISD::UNINDEXED)
425     return false;
426
427   ISD::LoadExtType ExtType = LD->getExtensionType();
428   if (ExtType != ISD::NON_EXTLOAD && ExtType != ISD::EXTLOAD)
429     return false;
430
431   return (N.hasOneUse() &&
432           LD->hasNUsesOfValue(1, 1) &&
433           LD->isOperandOf(Chain.getNode()));
434 }
435
436
437 /// isRMWLoad - Return true if N is a load that's part of RMW sub-DAG.
438 /// The chain produced by the load must only be used by the store's chain
439 /// operand, otherwise this may produce a cycle in the DAG.
440 static bool isRMWLoad(SDValue N, SDValue Chain, SDValue Address,
441                       SDValue &Load) {
442   if (isLoadAllowedToSink(N, Chain) &&
443       N.getOperand(1) == Address) {
444     Load = N;
445     return true;
446   }
447   return false;
448 }
449
450 /// PreprocessForRMW - Preprocess the DAG to make instruction selection better.
451 /// This is only run if not in -O0 mode.
452 /// This allows the instruction selector to pick more read-modify-write
453 /// instructions. This is a common case:
454 ///
455 ///     [Load chain]
456 ///         ^
457 ///         |
458 ///       [Load]
459 ///       ^    ^
460 ///       |    |
461 ///      /      \-
462 ///     /         |
463 /// [TokenFactor] [Op]
464 ///     ^          ^
465 ///     |          |
466 ///      \        /
467 ///       \      /
468 ///       [Store]
469 ///
470 /// The fact the store's chain operand != load's chain will prevent the
471 /// (store (op (load))) instruction from being selected. We can transform it to:
472 ///
473 ///     [Load chain]
474 ///         ^
475 ///         |
476 ///    [TokenFactor]
477 ///         ^
478 ///         |
479 ///       [Load]
480 ///       ^    ^
481 ///       |    |
482 ///       |     \-
483 ///       |       |
484 ///       |     [Op]
485 ///       |       ^
486 ///       |       |
487 ///       \      /
488 ///        \    /
489 ///       [Store]
490 ///
491 /// We also recognize the case where second operand of Op is load as well and
492 /// move it below token factor as well creating DAG as follows:
493 ///
494 ///       [Load chain]
495 ///            ^
496 ///            |
497 ///      [TokenFactor]
498 ///            ^
499 ///            |
500 ///         [Load1]
501 ///         ^     ^
502 ///        /      |
503 ///       /       |
504 ///       [Load2] |
505 ///       ^    ^  |
506 ///       |    |  |
507 ///       |     \-|
508 ///       |       |
509 ///       |     [Op]
510 ///       |       ^
511 ///       |       |
512 ///       \      /
513 ///        \    /
514 ///       [Store]
515 ///
516 /// This allows selection of mem-mem instructions. Yay!
517
518 void MSP430DAGToDAGISel::PreprocessForRMW() {
519   for (SelectionDAG::allnodes_iterator I = CurDAG->allnodes_begin(),
520          E = CurDAG->allnodes_end(); I != E; ++I) {
521     if (!ISD::isNON_TRUNCStore(I))
522       continue;
523     SDValue Chain = I->getOperand(0);
524
525     if (Chain.getNode()->getOpcode() != ISD::TokenFactor)
526       continue;
527
528     SDValue N1 = I->getOperand(1);
529     SDValue N2 = I->getOperand(2);
530     if ((N1.getValueType().isFloatingPoint() &&
531          !N1.getValueType().isVector()) ||
532         !N1.hasOneUse())
533       continue;
534
535     unsigned RModW = 0;
536     SDValue Load1, Load2;
537     unsigned Opcode = N1.getNode()->getOpcode();
538     switch (Opcode) {
539     case ISD::ADD:
540     case ISD::AND:
541     case ISD::OR:
542     case ISD::XOR:
543     case ISD::ADDC:
544     case ISD::ADDE: {
545       SDValue N10 = N1.getOperand(0);
546       SDValue N11 = N1.getOperand(1);
547       if (isRMWLoad(N10, Chain, N2, Load1)) {
548         if (isLoadAllowedToSink(N11, Chain)) {
549           Load2 = N11;
550           RModW = 2;
551         } else
552           RModW = 1;
553       } else if (isRMWLoad(N11, Chain, N2, Load1)) {
554         if (isLoadAllowedToSink(N10, Chain)) {
555           Load2 = N10;
556           RModW = 2;
557         } else
558           RModW = 1;
559       }
560       break;
561     }
562     case ISD::SUB:
563     case ISD::SUBC:
564     case ISD::SUBE: {
565       SDValue N10 = N1.getOperand(0);
566       SDValue N11 = N1.getOperand(1);
567       if (isRMWLoad(N10, Chain, N2, Load1)) {
568         if (isLoadAllowedToSink(N11, Chain)) {
569           Load2 = N11;
570           RModW = 2;
571         } else
572           RModW = 1;
573       }
574       break;
575     }
576     }
577
578     NumLoadMoved += RModW;
579     if (RModW == 1)
580       MoveBelowTokenFactor(CurDAG, Load1, SDValue(I, 0), Chain);
581     else if (RModW == 2) {
582       MoveBelowTokenFactor2(CurDAG, Load1, Load2, SDValue(I, 0), Chain);
583       SDNode* Store = I;
584       RMWStores[Store] = Load2.getNode();
585     }
586   }
587 }
588
589
590 static bool isValidIndexedLoad(const LoadSDNode *LD) {
591   ISD::MemIndexedMode AM = LD->getAddressingMode();
592   if (AM != ISD::POST_INC || LD->getExtensionType() != ISD::NON_EXTLOAD)
593     return false;
594
595   EVT VT = LD->getMemoryVT();
596
597   switch (VT.getSimpleVT().SimpleTy) {
598   case MVT::i8:
599     // Sanity check
600     if (cast<ConstantSDNode>(LD->getOffset())->getZExtValue() != 1)
601       return false;
602
603     break;
604   case MVT::i16:
605     // Sanity check
606     if (cast<ConstantSDNode>(LD->getOffset())->getZExtValue() != 2)
607       return false;
608
609     break;
610   default:
611     return false;
612   }
613
614   return true;
615 }
616
617 SDNode *MSP430DAGToDAGISel::SelectIndexedLoad(SDNode *N) {
618   LoadSDNode *LD = cast<LoadSDNode>(N);
619   if (!isValidIndexedLoad(LD))
620     return NULL;
621
622   MVT VT = LD->getMemoryVT().getSimpleVT();
623
624   unsigned Opcode = 0;
625   switch (VT.SimpleTy) {
626   case MVT::i8:
627     Opcode = MSP430::MOV8rm_POST;
628     break;
629   case MVT::i16:
630     Opcode = MSP430::MOV16rm_POST;
631     break;
632   default:
633     return NULL;
634   }
635
636    return CurDAG->getMachineNode(Opcode, N->getDebugLoc(),
637                                  VT, MVT::i16, MVT::Other,
638                                  LD->getBasePtr(), LD->getChain());
639 }
640
641 SDNode *MSP430DAGToDAGISel::SelectIndexedBinOp(SDNode *Op,
642                                                SDValue N1, SDValue N2,
643                                                unsigned Opc8, unsigned Opc16) {
644   if (N1.getOpcode() == ISD::LOAD &&
645       N1.hasOneUse() &&
646       IsLegalToFold(N1, Op, Op)) {
647     LoadSDNode *LD = cast<LoadSDNode>(N1);
648     if (!isValidIndexedLoad(LD))
649       return NULL;
650
651     MVT VT = LD->getMemoryVT().getSimpleVT();
652     unsigned Opc = (VT == MVT::i16 ? Opc16 : Opc8);
653     MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
654     MemRefs0[0] = cast<MemSDNode>(N1)->getMemOperand();
655     SDValue Ops0[] = { N2, LD->getBasePtr(), LD->getChain() };
656     SDNode *ResNode =
657       CurDAG->SelectNodeTo(Op, Opc,
658                            VT, MVT::i16, MVT::Other,
659                            Ops0, 3);
660     cast<MachineSDNode>(ResNode)->setMemRefs(MemRefs0, MemRefs0 + 1);
661     // Transfer chain.
662     ReplaceUses(SDValue(N1.getNode(), 2), SDValue(ResNode, 2));
663     // Transfer writeback.
664     ReplaceUses(SDValue(N1.getNode(), 1), SDValue(ResNode, 1));
665     return ResNode;
666   }
667
668   return NULL;
669 }
670
671
672 void MSP430DAGToDAGISel::PreprocessISelDAG() {
673   PreprocessForRMW();
674 }
675
676 void MSP430DAGToDAGISel::PostprocessISelDAG() {
677   RMWStores.clear();
678 }
679
680 SDNode *MSP430DAGToDAGISel::Select(SDNode *Node) {
681   DebugLoc dl = Node->getDebugLoc();
682
683   // Dump information about the Node being selected
684   DEBUG(errs() << "Selecting: ");
685   DEBUG(Node->dump(CurDAG));
686   DEBUG(errs() << "\n");
687
688   // If we have a custom node, we already have selected!
689   if (Node->isMachineOpcode()) {
690     DEBUG(errs() << "== ";
691           Node->dump(CurDAG);
692           errs() << "\n");
693     return NULL;
694   }
695
696   // Few custom selection stuff.
697   switch (Node->getOpcode()) {
698   default: break;
699   case ISD::FrameIndex: {
700     assert(Node->getValueType(0) == MVT::i16);
701     int FI = cast<FrameIndexSDNode>(Node)->getIndex();
702     SDValue TFI = CurDAG->getTargetFrameIndex(FI, MVT::i16);
703     if (Node->hasOneUse())
704       return CurDAG->SelectNodeTo(Node, MSP430::ADD16ri, MVT::i16,
705                                   TFI, CurDAG->getTargetConstant(0, MVT::i16));
706     return CurDAG->getMachineNode(MSP430::ADD16ri, dl, MVT::i16,
707                                   TFI, CurDAG->getTargetConstant(0, MVT::i16));
708   }
709   case ISD::LOAD:
710     if (SDNode *ResNode = SelectIndexedLoad(Node))
711       return ResNode;
712     // Other cases are autogenerated.
713     break;
714   case ISD::ADD:
715     if (SDNode *ResNode =
716         SelectIndexedBinOp(Node,
717                            Node->getOperand(0), Node->getOperand(1),
718                            MSP430::ADD8rm_POST, MSP430::ADD16rm_POST))
719       return ResNode;
720     else if (SDNode *ResNode =
721              SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0),
722                                 MSP430::ADD8rm_POST, MSP430::ADD16rm_POST))
723       return ResNode;
724
725     // Other cases are autogenerated.
726     break;
727   case ISD::SUB:
728     if (SDNode *ResNode =
729         SelectIndexedBinOp(Node,
730                            Node->getOperand(0), Node->getOperand(1),
731                            MSP430::SUB8rm_POST, MSP430::SUB16rm_POST))
732       return ResNode;
733
734     // Other cases are autogenerated.
735     break;
736   case ISD::AND:
737     if (SDNode *ResNode =
738         SelectIndexedBinOp(Node,
739                            Node->getOperand(0), Node->getOperand(1),
740                            MSP430::AND8rm_POST, MSP430::AND16rm_POST))
741       return ResNode;
742     else if (SDNode *ResNode =
743              SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0),
744                                 MSP430::AND8rm_POST, MSP430::AND16rm_POST))
745       return ResNode;
746
747     // Other cases are autogenerated.
748     break;
749   case ISD::OR:
750     if (SDNode *ResNode =
751         SelectIndexedBinOp(Node,
752                            Node->getOperand(0), Node->getOperand(1),
753                            MSP430::OR8rm_POST, MSP430::OR16rm_POST))
754       return ResNode;
755     else if (SDNode *ResNode =
756              SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0),
757                                 MSP430::OR8rm_POST, MSP430::OR16rm_POST))
758       return ResNode;
759
760     // Other cases are autogenerated.
761     break;
762   case ISD::XOR:
763     if (SDNode *ResNode =
764         SelectIndexedBinOp(Node,
765                            Node->getOperand(0), Node->getOperand(1),
766                            MSP430::XOR8rm_POST, MSP430::XOR16rm_POST))
767       return ResNode;
768     else if (SDNode *ResNode =
769              SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0),
770                                 MSP430::XOR8rm_POST, MSP430::XOR16rm_POST))
771       return ResNode;
772
773     // Other cases are autogenerated.
774     break;
775   }
776
777   // Select the default instruction
778   SDNode *ResNode = SelectCode(Node);
779
780   DEBUG(errs() << "=> ");
781   if (ResNode == NULL || ResNode == Node)
782     DEBUG(Node->dump(CurDAG));
783   else
784     DEBUG(ResNode->dump(CurDAG));
785   DEBUG(errs() << "\n");
786
787   return ResNode;
788 }