MSP430ISelDAGToDAG.cpp revision 263508
1119452Sobrien//===-- MSP430ISelDAGToDAG.cpp - A dag to dag inst selector for MSP430 ----===//
2101225Sphk//
3101225Sphk//                     The LLVM Compiler Infrastructure
4101225Sphk//
5101225Sphk// This file is distributed under the University of Illinois Open Source
6101225Sphk// License. See LICENSE.TXT for details.
7101225Sphk//
8101225Sphk//===----------------------------------------------------------------------===//
9101225Sphk//
10102934Sphk// This file defines an instruction selector for the MSP430 target.
11102934Sphk//
12102934Sphk//===----------------------------------------------------------------------===//
13102934Sphk
14102934Sphk#include "MSP430.h"
15102934Sphk#include "MSP430TargetMachine.h"
16102934Sphk#include "llvm/CodeGen/MachineFrameInfo.h"
17102934Sphk#include "llvm/CodeGen/MachineFunction.h"
18102934Sphk#include "llvm/CodeGen/MachineInstrBuilder.h"
19109327Sphk#include "llvm/CodeGen/MachineRegisterInfo.h"
20123015Sphk#include "llvm/CodeGen/SelectionDAG.h"
21123015Sphk#include "llvm/CodeGen/SelectionDAGISel.h"
22123015Sphk#include "llvm/IR/CallingConv.h"
23123015Sphk#include "llvm/IR/Constants.h"
24123015Sphk#include "llvm/IR/DerivedTypes.h"
25123015Sphk#include "llvm/IR/Function.h"
26123015Sphk#include "llvm/IR/Intrinsics.h"
27123015Sphk#include "llvm/Support/Compiler.h"
28123015Sphk#include "llvm/Support/Debug.h"
29123015Sphk#include "llvm/Support/ErrorHandling.h"
30123015Sphk#include "llvm/Support/raw_ostream.h"
31123015Sphk#include "llvm/Target/TargetLowering.h"
32123015Sphkusing namespace llvm;
33123015Sphk
34123015Sphknamespace {
35123015Sphk  struct MSP430ISelAddressMode {
36123015Sphk    enum {
37123015Sphk      RegBase,
38123015Sphk      FrameIndexBase
39101225Sphk    } BaseType;
40102934Sphk
41115683Sobrien    struct {            // This is really a union, discriminated by BaseType!
42115683Sobrien      SDValue Reg;
43115683Sobrien      int FrameIndex;
44111138Sphk    } Base;
45101225Sphk
46101225Sphk    int16_t Disp;
47101225Sphk    const GlobalValue *GV;
48101225Sphk    const Constant *CP;
49102934Sphk    const BlockAddress *BlockAddr;
50123015Sphk    const char *ES;
51102934Sphk    int JT;
52102934Sphk    unsigned Align;    // CP alignment.
53103482Sphk
54103482Sphk    MSP430ISelAddressMode()
55103482Sphk      : BaseType(RegBase), Disp(0), GV(0), CP(0), BlockAddr(0),
56103482Sphk        ES(0), JT(-1), Align(0) {
57109327Sphk    }
58109327Sphk
59111647Sphk    bool hasSymbolicDisplacement() const {
60101225Sphk      return GV != 0 || CP != 0 || ES != 0 || JT != -1;
61121944Sphk    }
62101225Sphk
63124144Sphk    void dump() {
64101225Sphk      errs() << "MSP430ISelAddressMode " << this << '\n';
65102934Sphk      if (BaseType == RegBase && Base.Reg.getNode() != 0) {
66102934Sphk        errs() << "Base.Reg ";
67102934Sphk        Base.Reg.getNode()->dump();
68123015Sphk      } else if (BaseType == FrameIndexBase) {
69123015Sphk        errs() << " Base.FrameIndex " << Base.FrameIndex << '\n';
70124144Sphk      }
71127039Sphk      errs() << " Disp " << Disp << '\n';
72102934Sphk      if (GV) {
73123015Sphk        errs() << "GV ";
74109327Sphk        GV->dump();
75127039Sphk      } else if (CP) {
76127039Sphk        errs() << " CP ";
77127039Sphk        CP->dump();
78123015Sphk        errs() << " Align" << Align << '\n';
79127039Sphk      } else if (ES) {
80127039Sphk        errs() << "ES ";
81130585Sphk        errs() << ES << '\n';
82109327Sphk      } else if (JT != -1)
83109327Sphk        errs() << " JT" << JT << " Align" << Align << '\n';
84123015Sphk    }
85123015Sphk  };
86123015Sphk}
87123015Sphk
88123015Sphk/// MSP430DAGToDAGISel - MSP430 specific code to select MSP430 machine
89123015Sphk/// instructions for SelectionDAG operations.
90123015Sphk///
91123015Sphknamespace {
92123015Sphk  class MSP430DAGToDAGISel : public SelectionDAGISel {
93124144Sphk    const MSP430TargetLowering &Lowering;
94123015Sphk    const MSP430Subtarget &Subtarget;
95123015Sphk
96123015Sphk  public:
97123015Sphk    MSP430DAGToDAGISel(MSP430TargetMachine &TM, CodeGenOpt::Level OptLevel)
98123015Sphk      : SelectionDAGISel(TM, OptLevel),
99123015Sphk        Lowering(*TM.getTargetLowering()),
100123015Sphk        Subtarget(*TM.getSubtargetImpl()) { }
101123015Sphk
102126762Sjb    virtual const char *getPassName() const {
103126762Sjb      return "MSP430 DAG->DAG Pattern Instruction Selection";
104126762Sjb    }
105126762Sjb
106123015Sphk    bool MatchAddress(SDValue N, MSP430ISelAddressMode &AM);
107123015Sphk    bool MatchWrapper(SDValue N, MSP430ISelAddressMode &AM);
108123015Sphk    bool MatchAddressBase(SDValue N, MSP430ISelAddressMode &AM);
109123015Sphk
110123015Sphk    virtual bool
111123015Sphk    SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
112123015Sphk                                 std::vector<SDValue> &OutOps);
113123015Sphk
114123015Sphk    // Include the pieces autogenerated from the target description.
115123015Sphk  #include "MSP430GenDAGISel.inc"
116123015Sphk
117123015Sphk  private:
118127801Sphk    SDNode *Select(SDNode *N);
119127801Sphk    SDNode *SelectIndexedLoad(SDNode *Op);
120127801Sphk    SDNode *SelectIndexedBinOp(SDNode *Op, SDValue N1, SDValue N2,
121123015Sphk                               unsigned Opc8, unsigned Opc16);
122123015Sphk
123123015Sphk    bool SelectAddr(SDValue Addr, SDValue &Base, SDValue &Disp);
124123015Sphk  };
125123015Sphk}  // end anonymous namespace
126123015Sphk
127123015Sphk/// createMSP430ISelDag - This pass converts a legalized DAG into a
128123015Sphk/// MSP430-specific DAG, ready for instruction scheduling.
129123015Sphk///
130123015SphkFunctionPass *llvm::createMSP430ISelDag(MSP430TargetMachine &TM,
131123015Sphk                                        CodeGenOpt::Level OptLevel) {
132123015Sphk  return new MSP430DAGToDAGISel(TM, OptLevel);
133123015Sphk}
134123015Sphk
135123015Sphk
136123015Sphk/// MatchWrapper - Try to match MSP430ISD::Wrapper node into an addressing mode.
137123015Sphk/// These wrap things that will resolve down into a symbol reference.  If no
138123015Sphk/// match is possible, this returns true, otherwise it returns false.
139123015Sphkbool MSP430DAGToDAGISel::MatchWrapper(SDValue N, MSP430ISelAddressMode &AM) {
140123015Sphk  // If the addressing mode already has a symbol as the displacement, we can
141123015Sphk  // never match another symbol.
142123015Sphk  if (AM.hasSymbolicDisplacement())
143123015Sphk    return true;
144123015Sphk
145123015Sphk  SDValue N0 = N.getOperand(0);
146123015Sphk
147123015Sphk  if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(N0)) {
148123015Sphk    AM.GV = G->getGlobal();
149123015Sphk    AM.Disp += G->getOffset();
150123015Sphk    //AM.SymbolFlags = G->getTargetFlags();
151126762Sjb  } else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(N0)) {
152127801Sphk    AM.CP = CP->getConstVal();
153127801Sphk    AM.Align = CP->getAlignment();
154127801Sphk    AM.Disp += CP->getOffset();
155127801Sphk    //AM.SymbolFlags = CP->getTargetFlags();
156123015Sphk  } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(N0)) {
157123015Sphk    AM.ES = S->getSymbol();
158123015Sphk    //AM.SymbolFlags = S->getTargetFlags();
159124144Sphk  } else if (JumpTableSDNode *J = dyn_cast<JumpTableSDNode>(N0)) {
160123015Sphk    AM.JT = J->getIndex();
161123015Sphk    //AM.SymbolFlags = J->getTargetFlags();
162123015Sphk  } else {
163123015Sphk    AM.BlockAddr = cast<BlockAddressSDNode>(N0)->getBlockAddress();
164123015Sphk    //AM.SymbolFlags = cast<BlockAddressSDNode>(N0)->getTargetFlags();
165123015Sphk  }
166127039Sphk  return false;
167127039Sphk}
168127039Sphk
169124144Sphk/// MatchAddressBase - Helper for MatchAddress. Add the specified node to the
170123015Sphk/// specified addressing mode without any further recursion.
171123015Sphkbool MSP430DAGToDAGISel::MatchAddressBase(SDValue N, MSP430ISelAddressMode &AM) {
172123015Sphk  // Is the base register already occupied?
173123015Sphk  if (AM.BaseType != MSP430ISelAddressMode::RegBase || AM.Base.Reg.getNode()) {
174123015Sphk    // If so, we cannot select it.
175123015Sphk    return true;
176123015Sphk  }
177123015Sphk
178123015Sphk  // Default, generate it as a register.
179124144Sphk  AM.BaseType = MSP430ISelAddressMode::RegBase;
180123015Sphk  AM.Base.Reg = N;
181123015Sphk  return false;
182123015Sphk}
183123015Sphk
184123015Sphkbool MSP430DAGToDAGISel::MatchAddress(SDValue N, MSP430ISelAddressMode &AM) {
185123015Sphk  DEBUG(errs() << "MatchAddress: "; AM.dump());
186123015Sphk
187123015Sphk  switch (N.getOpcode()) {
188123015Sphk  default: break;
189123015Sphk  case ISD::Constant: {
190123015Sphk    uint64_t Val = cast<ConstantSDNode>(N)->getSExtValue();
191123015Sphk    AM.Disp += Val;
192128677Sphk    return false;
193128677Sphk  }
194123015Sphk
195123015Sphk  case MSP430ISD::Wrapper:
196123015Sphk    if (!MatchWrapper(N, AM))
197123015Sphk      return false;
198123015Sphk    break;
199123015Sphk
200123015Sphk  case ISD::FrameIndex:
201123015Sphk    if (AM.BaseType == MSP430ISelAddressMode::RegBase
202123015Sphk        && AM.Base.Reg.getNode() == 0) {
203123015Sphk      AM.BaseType = MSP430ISelAddressMode::FrameIndexBase;
204123015Sphk      AM.Base.FrameIndex = cast<FrameIndexSDNode>(N)->getIndex();
205123015Sphk      return false;
206123015Sphk    }
207123015Sphk    break;
208123015Sphk
209123015Sphk  case ISD::ADD: {
210123015Sphk    MSP430ISelAddressMode Backup = AM;
211123015Sphk    if (!MatchAddress(N.getNode()->getOperand(0), AM) &&
212123015Sphk        !MatchAddress(N.getNode()->getOperand(1), AM))
213109327Sphk      return false;
214109327Sphk    AM = Backup;
215109327Sphk    if (!MatchAddress(N.getNode()->getOperand(1), AM) &&
216109327Sphk        !MatchAddress(N.getNode()->getOperand(0), AM))
217127039Sphk      return false;
218127039Sphk    AM = Backup;
219109327Sphk
220123015Sphk    break;
221127039Sphk  }
222127039Sphk
223127039Sphk  case ISD::OR:
224127039Sphk    // Handle "X | C" as "X + C" iff X is known to have C bits clear.
225127039Sphk    if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
226127039Sphk      MSP430ISelAddressMode Backup = AM;
227127039Sphk      uint64_t Offset = CN->getSExtValue();
228127039Sphk      // Start with the LHS as an addr mode.
229127039Sphk      if (!MatchAddress(N.getOperand(0), AM) &&
230127039Sphk          // Address could not have picked a GV address for the displacement.
231127039Sphk          AM.GV == NULL &&
232127039Sphk          // Check to see if the LHS & C is zero.
233123015Sphk          CurDAG->MaskedValueIsZero(N.getOperand(0), CN->getAPIntValue())) {
234123015Sphk        AM.Disp += Offset;
235123015Sphk        return false;
236123015Sphk      }
237123015Sphk      AM = Backup;
238123015Sphk    }
239123015Sphk    break;
240127039Sphk  }
241123015Sphk
242123015Sphk  return MatchAddressBase(N, AM);
243123015Sphk}
244109327Sphk
245123015Sphk/// SelectAddr - returns true if it is able pattern match an addressing mode.
246109327Sphk/// It returns the operands which make up the maximal addressing mode it can
247123015Sphk/// match by reference.
248123015Sphkbool MSP430DAGToDAGISel::SelectAddr(SDValue N,
249123015Sphk                                    SDValue &Base, SDValue &Disp) {
250123015Sphk  MSP430ISelAddressMode AM;
251124144Sphk
252109327Sphk  if (MatchAddress(N, AM))
253123015Sphk    return false;
254123015Sphk
255127039Sphk  EVT VT = N.getValueType();
256127039Sphk  if (AM.BaseType == MSP430ISelAddressMode::RegBase) {
257127039Sphk    if (!AM.Base.Reg.getNode())
258127039Sphk      AM.Base.Reg = CurDAG->getRegister(0, VT);
259127039Sphk  }
260127039Sphk
261109327Sphk  Base  = (AM.BaseType == MSP430ISelAddressMode::FrameIndexBase) ?
262127039Sphk    CurDAG->getTargetFrameIndex(AM.Base.FrameIndex,
263109327Sphk                                getTargetLowering()->getPointerTy()) :
264123015Sphk    AM.Base.Reg;
265123015Sphk
266123015Sphk  if (AM.GV)
267124144Sphk    Disp = CurDAG->getTargetGlobalAddress(AM.GV, SDLoc(N),
268109327Sphk                                          MVT::i16, AM.Disp,
269123015Sphk                                          0/*AM.SymbolFlags*/);
270109327Sphk  else if (AM.CP)
271102935Sphk    Disp = CurDAG->getTargetConstantPool(AM.CP, MVT::i16,
272102935Sphk                                         AM.Align, AM.Disp, 0/*AM.SymbolFlags*/);
273102935Sphk  else if (AM.ES)
274123015Sphk    Disp = CurDAG->getTargetExternalSymbol(AM.ES, MVT::i16, 0/*AM.SymbolFlags*/);
275123015Sphk  else if (AM.JT != -1)
276124144Sphk    Disp = CurDAG->getTargetJumpTable(AM.JT, MVT::i16, 0/*AM.SymbolFlags*/);
277102935Sphk  else if (AM.BlockAddr)
278102935Sphk    Disp = CurDAG->getTargetBlockAddress(AM.BlockAddr, MVT::i32, 0,
279109327Sphk                                         0/*AM.SymbolFlags*/);
280109327Sphk  else
281109327Sphk    Disp = CurDAG->getTargetConstant(AM.Disp, MVT::i16);
282109327Sphk
283123015Sphk  return true;
284123015Sphk}
285109327Sphk
286109327Sphkbool MSP430DAGToDAGISel::
287102935SphkSelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
288102935Sphk                             std::vector<SDValue> &OutOps) {
289109327Sphk  SDValue Op0, Op1;
290102935Sphk  switch (ConstraintCode) {
291123015Sphk  default: return true;
292119715Sphk  case 'm':   // memory
293119715Sphk    if (!SelectAddr(Op, Op0, Op1))
294102935Sphk      return true;
295102935Sphk    break;
296109327Sphk  }
297109327Sphk
298109327Sphk  OutOps.push_back(Op0);
299109327Sphk  OutOps.push_back(Op1);
300109327Sphk  return false;
301109327Sphk}
302109327Sphk
303109327Sphkstatic bool isValidIndexedLoad(const LoadSDNode *LD) {
304109327Sphk  ISD::MemIndexedMode AM = LD->getAddressingMode();
305109327Sphk  if (AM != ISD::POST_INC || LD->getExtensionType() != ISD::NON_EXTLOAD)
306109327Sphk    return false;
307109327Sphk
308109327Sphk  EVT VT = LD->getMemoryVT();
309109327Sphk
310109327Sphk  switch (VT.getSimpleVT().SimpleTy) {
311109327Sphk  case MVT::i8:
312123015Sphk    // Sanity check
313123015Sphk    if (cast<ConstantSDNode>(LD->getOffset())->getZExtValue() != 1)
314123015Sphk      return false;
315123015Sphk
316102934Sphk    break;
317102934Sphk  case MVT::i16:
318102934Sphk    // Sanity check
319102934Sphk    if (cast<ConstantSDNode>(LD->getOffset())->getZExtValue() != 2)
320102934Sphk      return false;
321102934Sphk
322124144Sphk    break;
323124144Sphk  default:
324102934Sphk    return false;
325102934Sphk  }
326102934Sphk
327102934Sphk  return true;
328102934Sphk}
329123015Sphk
330102934SphkSDNode *MSP430DAGToDAGISel::SelectIndexedLoad(SDNode *N) {
331102934Sphk  LoadSDNode *LD = cast<LoadSDNode>(N);
332102934Sphk  if (!isValidIndexedLoad(LD))
333102934Sphk    return NULL;
334123015Sphk
335123015Sphk  MVT VT = LD->getMemoryVT().getSimpleVT();
336103168Ssam
337102935Sphk  unsigned Opcode = 0;
338102935Sphk  switch (VT.SimpleTy) {
339124144Sphk  case MVT::i8:
340124144Sphk    Opcode = MSP430::MOV8rm_POST;
341109327Sphk    break;
342123015Sphk  case MVT::i16:
343109327Sphk    Opcode = MSP430::MOV16rm_POST;
344124144Sphk    break;
345124144Sphk  default:
346124144Sphk    return NULL;
347124144Sphk  }
348109327Sphk
349109327Sphk   return CurDAG->getMachineNode(Opcode, SDLoc(N),
350109327Sphk                                 VT, MVT::i16, MVT::Other,
351102935Sphk                                 LD->getBasePtr(), LD->getChain());
352102934Sphk}
353102934Sphk
354103482SphkSDNode *MSP430DAGToDAGISel::SelectIndexedBinOp(SDNode *Op,
355126370Sphk                                               SDValue N1, SDValue N2,
356101225Sphk                                               unsigned Opc8, unsigned Opc16) {
357111647Sphk  if (N1.getOpcode() == ISD::LOAD &&
358111647Sphk      N1.hasOneUse() &&
359111647Sphk      IsLegalToFold(N1, Op, Op, OptLevel)) {
360126370Sphk    LoadSDNode *LD = cast<LoadSDNode>(N1);
361126370Sphk    if (!isValidIndexedLoad(LD))
362111647Sphk      return NULL;
363111647Sphk
364111647Sphk    MVT VT = LD->getMemoryVT().getSimpleVT();
365111647Sphk    unsigned Opc = (VT == MVT::i16 ? Opc16 : Opc8);
366111647Sphk    MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
367111647Sphk    MemRefs0[0] = cast<MemSDNode>(N1)->getMemOperand();
368111647Sphk    SDValue Ops0[] = { N2, LD->getBasePtr(), LD->getChain() };
369111647Sphk    SDNode *ResNode =
370111647Sphk      CurDAG->SelectNodeTo(Op, Opc,
371111647Sphk                           VT, MVT::i16, MVT::Other,
372111647Sphk                           Ops0, 3);
373124144Sphk    cast<MachineSDNode>(ResNode)->setMemRefs(MemRefs0, MemRefs0 + 1);
374124144Sphk    // Transfer chain.
375111647Sphk    ReplaceUses(SDValue(N1.getNode(), 2), SDValue(ResNode, 2));
376111647Sphk    // Transfer writeback.
377124144Sphk    ReplaceUses(SDValue(N1.getNode(), 1), SDValue(ResNode, 1));
378124144Sphk    return ResNode;
379124144Sphk  }
380111647Sphk
381111647Sphk  return NULL;
382124144Sphk}
383124144Sphk
384124144Sphk
385111647SphkSDNode *MSP430DAGToDAGISel::Select(SDNode *Node) {
386111647Sphk  SDLoc dl(Node);
387111647Sphk
388124144Sphk  // Dump information about the Node being selected
389124144Sphk  DEBUG(errs() << "Selecting: ");
390111647Sphk  DEBUG(Node->dump(CurDAG));
391124144Sphk  DEBUG(errs() << "\n");
392126370Sphk
393126370Sphk  // If we have a custom node, we already have selected!
394126370Sphk  if (Node->isMachineOpcode()) {
395124144Sphk    DEBUG(errs() << "== ";
396124144Sphk          Node->dump(CurDAG);
397124144Sphk          errs() << "\n");
398124144Sphk    Node->setNodeId(-1);
399124144Sphk    return NULL;
400124144Sphk  }
401124144Sphk
402111647Sphk  // Few custom selection stuff.
403126370Sphk  switch (Node->getOpcode()) {
404111647Sphk  default: break;
405111647Sphk  case ISD::FrameIndex: {
406111647Sphk    assert(Node->getValueType(0) == MVT::i16);
407111647Sphk    int FI = cast<FrameIndexSDNode>(Node)->getIndex();
408130585Sphk    SDValue TFI = CurDAG->getTargetFrameIndex(FI, MVT::i16);
409126370Sphk    if (Node->hasOneUse())
410126370Sphk      return CurDAG->SelectNodeTo(Node, MSP430::ADD16ri, MVT::i16,
411126370Sphk                                  TFI, CurDAG->getTargetConstant(0, MVT::i16));
412126370Sphk    return CurDAG->getMachineNode(MSP430::ADD16ri, dl, MVT::i16,
413126370Sphk                                  TFI, CurDAG->getTargetConstant(0, MVT::i16));
414126370Sphk  }
415126370Sphk  case ISD::LOAD:
416126370Sphk    if (SDNode *ResNode = SelectIndexedLoad(Node))
417130585Sphk      return ResNode;
418101225Sphk    // Other cases are autogenerated.
419109327Sphk    break;
420109327Sphk  case ISD::ADD:
421126370Sphk    if (SDNode *ResNode =
422123015Sphk        SelectIndexedBinOp(Node,
423123015Sphk                           Node->getOperand(0), Node->getOperand(1),
424123015Sphk                           MSP430::ADD8rm_POST, MSP430::ADD16rm_POST))
425123015Sphk      return ResNode;
426109327Sphk    else if (SDNode *ResNode =
427109327Sphk             SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0),
428109327Sphk                                MSP430::ADD8rm_POST, MSP430::ADD16rm_POST))
429109327Sphk      return ResNode;
430123015Sphk
431109327Sphk    // Other cases are autogenerated.
432123015Sphk    break;
433109327Sphk  case ISD::SUB:
434123015Sphk    if (SDNode *ResNode =
435126370Sphk        SelectIndexedBinOp(Node,
436109327Sphk                           Node->getOperand(0), Node->getOperand(1),
437123015Sphk                           MSP430::SUB8rm_POST, MSP430::SUB16rm_POST))
438109327Sphk      return ResNode;
439109327Sphk
440101225Sphk    // Other cases are autogenerated.
441101225Sphk    break;
442126370Sphk  case ISD::AND:
443126370Sphk    if (SDNode *ResNode =
444126370Sphk        SelectIndexedBinOp(Node,
445126370Sphk                           Node->getOperand(0), Node->getOperand(1),
446126370Sphk                           MSP430::AND8rm_POST, MSP430::AND16rm_POST))
447126370Sphk      return ResNode;
448126370Sphk    else if (SDNode *ResNode =
449126370Sphk             SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0),
450126370Sphk                                MSP430::AND8rm_POST, MSP430::AND16rm_POST))
451126370Sphk      return ResNode;
452126370Sphk
453126370Sphk    // Other cases are autogenerated.
454126370Sphk    break;
455126370Sphk  case ISD::OR:
456126370Sphk    if (SDNode *ResNode =
457126370Sphk        SelectIndexedBinOp(Node,
458126370Sphk                           Node->getOperand(0), Node->getOperand(1),
459126370Sphk                           MSP430::OR8rm_POST, MSP430::OR16rm_POST))
460126370Sphk      return ResNode;
461126370Sphk    else if (SDNode *ResNode =
462126370Sphk             SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0),
463126370Sphk                                MSP430::OR8rm_POST, MSP430::OR16rm_POST))
464126370Sphk      return ResNode;
465126370Sphk
466126370Sphk    // Other cases are autogenerated.
467126370Sphk    break;
468126370Sphk  case ISD::XOR:
469126370Sphk    if (SDNode *ResNode =
470126370Sphk        SelectIndexedBinOp(Node,
471126370Sphk                           Node->getOperand(0), Node->getOperand(1),
472126370Sphk                           MSP430::XOR8rm_POST, MSP430::XOR16rm_POST))
473126370Sphk      return ResNode;
474126370Sphk    else if (SDNode *ResNode =
475126370Sphk             SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0),
476126370Sphk                                MSP430::XOR8rm_POST, MSP430::XOR16rm_POST))
477126370Sphk      return ResNode;
478126370Sphk
479126370Sphk    // Other cases are autogenerated.
480126370Sphk    break;
481126370Sphk  }
482126370Sphk
483126370Sphk  // Select the default instruction
484126370Sphk  SDNode *ResNode = SelectCode(Node);
485126370Sphk
486126370Sphk  DEBUG(errs() << "=> ");
487  if (ResNode == NULL || ResNode == Node)
488    DEBUG(Node->dump(CurDAG));
489  else
490    DEBUG(ResNode->dump(CurDAG));
491  DEBUG(errs() << "\n");
492
493  return ResNode;
494}
495