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