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