MSP430ISelDAGToDAG.cpp revision 207618
117721Speter//===-- MSP430ISelDAGToDAG.cpp - A dag to dag inst selector for MSP430 ----===//
217721Speter//
317721Speter//                     The LLVM Compiler Infrastructure
417721Speter//
517721Speter// This file is distributed under the University of Illinois Open Source
617721Speter// License. See LICENSE.TXT for details.
717721Speter//
817721Speter//===----------------------------------------------------------------------===//
917721Speter//
1017721Speter// This file defines an instruction selector for the MSP430 target.
1117721Speter//
1217721Speter//===----------------------------------------------------------------------===//
1317721Speter
1417721Speter#include "MSP430.h"
1517721Speter#include "MSP430TargetMachine.h"
1617721Speter#include "llvm/DerivedTypes.h"
1717721Speter#include "llvm/Function.h"
1817721Speter#include "llvm/Intrinsics.h"
1917721Speter#include "llvm/CallingConv.h"
2017721Speter#include "llvm/Constants.h"
2117721Speter#include "llvm/CodeGen/MachineFrameInfo.h"
2217721Speter#include "llvm/CodeGen/MachineFunction.h"
2317721Speter#include "llvm/CodeGen/MachineInstrBuilder.h"
2417721Speter#include "llvm/CodeGen/MachineRegisterInfo.h"
2517721Speter#include "llvm/CodeGen/SelectionDAG.h"
2617721Speter#include "llvm/CodeGen/SelectionDAGISel.h"
2717721Speter#include "llvm/Target/TargetLowering.h"
2817721Speter#include "llvm/Support/Compiler.h"
2917721Speter#include "llvm/Support/Debug.h"
3017721Speter#include "llvm/Support/ErrorHandling.h"
3117721Speter#include "llvm/Support/raw_ostream.h"
3217721Speterusing namespace llvm;
3317721Speter
3417721Speternamespace {
3517721Speter  struct MSP430ISelAddressMode {
3617721Speter    enum {
3717721Speter      RegBase,
3817721Speter      FrameIndexBase
3917721Speter    } BaseType;
4017721Speter
4117721Speter    struct {            // This is really a union, discriminated by BaseType!
4217721Speter      SDValue Reg;
4317721Speter      int FrameIndex;
4417721Speter    } Base;
4517721Speter
4617721Speter    int16_t Disp;
4717721Speter    const GlobalValue *GV;
4817721Speter    const Constant *CP;
4917721Speter    const BlockAddress *BlockAddr;
5017721Speter    const char *ES;
5117721Speter    int JT;
5217721Speter    unsigned Align;    // CP alignment.
5317721Speter
5417721Speter    MSP430ISelAddressMode()
5517721Speter      : BaseType(RegBase), Disp(0), GV(0), CP(0), BlockAddr(0),
5617721Speter        ES(0), JT(-1), Align(0) {
5717721Speter    }
5817721Speter
5917721Speter    bool hasSymbolicDisplacement() const {
6017721Speter      return GV != 0 || CP != 0 || ES != 0 || JT != -1;
6117721Speter    }
6217721Speter
6317721Speter    bool hasBaseReg() const {
6417721Speter      return Base.Reg.getNode() != 0;
6517721Speter    }
6617721Speter
6717721Speter    void setBaseReg(SDValue Reg) {
6817721Speter      BaseType = RegBase;
6917721Speter      Base.Reg = Reg;
7017721Speter    }
7117721Speter
7217721Speter    void dump() {
7317721Speter      errs() << "MSP430ISelAddressMode " << this << '\n';
7417721Speter      if (BaseType == RegBase && Base.Reg.getNode() != 0) {
7517721Speter        errs() << "Base.Reg ";
7617721Speter        Base.Reg.getNode()->dump();
7717721Speter      } else if (BaseType == FrameIndexBase) {
7817721Speter        errs() << " Base.FrameIndex " << Base.FrameIndex << '\n';
7917721Speter      }
8017721Speter      errs() << " Disp " << Disp << '\n';
8117721Speter      if (GV) {
8217721Speter        errs() << "GV ";
8317721Speter        GV->dump();
8417721Speter      } else if (CP) {
8517721Speter        errs() << " CP ";
8617721Speter        CP->dump();
8717721Speter        errs() << " Align" << Align << '\n';
8817721Speter      } else if (ES) {
8917721Speter        errs() << "ES ";
9017721Speter        errs() << ES << '\n';
9117721Speter      } else if (JT != -1)
9217721Speter        errs() << " JT" << JT << " Align" << Align << '\n';
9317721Speter    }
9417721Speter  };
9517721Speter}
9617721Speter
9717721Speter/// MSP430DAGToDAGISel - MSP430 specific code to select MSP430 machine
9817721Speter/// instructions for SelectionDAG operations.
9917721Speter///
10017721Speternamespace {
10117721Speter  class MSP430DAGToDAGISel : public SelectionDAGISel {
10217721Speter    const MSP430TargetLowering &Lowering;
10317721Speter    const MSP430Subtarget &Subtarget;
10417721Speter
10517721Speter  public:
10617721Speter    MSP430DAGToDAGISel(MSP430TargetMachine &TM, CodeGenOpt::Level OptLevel)
10717721Speter      : SelectionDAGISel(TM, OptLevel),
10817721Speter        Lowering(*TM.getTargetLowering()),
10917721Speter        Subtarget(*TM.getSubtargetImpl()) { }
11017721Speter
11117721Speter    virtual const char *getPassName() const {
11217721Speter      return "MSP430 DAG->DAG Pattern Instruction Selection";
11317721Speter    }
11417721Speter
11517721Speter    bool MatchAddress(SDValue N, MSP430ISelAddressMode &AM);
11617721Speter    bool MatchWrapper(SDValue N, MSP430ISelAddressMode &AM);
11717721Speter    bool MatchAddressBase(SDValue N, MSP430ISelAddressMode &AM);
11817721Speter
11917721Speter    virtual bool
12017721Speter    SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
12117721Speter                                 std::vector<SDValue> &OutOps);
12217721Speter
12317721Speter    // Include the pieces autogenerated from the target description.
12417721Speter  #include "MSP430GenDAGISel.inc"
12517721Speter
12617721Speter  private:
12717721Speter    SDNode *Select(SDNode *N);
12817721Speter    SDNode *SelectIndexedLoad(SDNode *Op);
12917721Speter    SDNode *SelectIndexedBinOp(SDNode *Op, SDValue N1, SDValue N2,
13017721Speter                               unsigned Opc8, unsigned Opc16);
13117721Speter
13217721Speter    bool SelectAddr(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Disp);
13317721Speter  };
13417721Speter}  // end anonymous namespace
13517721Speter
13617721Speter/// createMSP430ISelDag - This pass converts a legalized DAG into a
13717721Speter/// MSP430-specific DAG, ready for instruction scheduling.
13817721Speter///
13917721SpeterFunctionPass *llvm::createMSP430ISelDag(MSP430TargetMachine &TM,
14017721Speter                                        CodeGenOpt::Level OptLevel) {
14117721Speter  return new MSP430DAGToDAGISel(TM, OptLevel);
14217721Speter}
14317721Speter
14417721Speter
14517721Speter/// MatchWrapper - Try to match MSP430ISD::Wrapper node into an addressing mode.
14617721Speter/// These wrap things that will resolve down into a symbol reference.  If no
14717721Speter/// match is possible, this returns true, otherwise it returns false.
14817721Speterbool MSP430DAGToDAGISel::MatchWrapper(SDValue N, MSP430ISelAddressMode &AM) {
14917721Speter  // If the addressing mode already has a symbol as the displacement, we can
15017721Speter  // never match another symbol.
15117721Speter  if (AM.hasSymbolicDisplacement())
15217721Speter    return true;
15317721Speter
15417721Speter  SDValue N0 = N.getOperand(0);
15517721Speter
15617721Speter  if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(N0)) {
15717721Speter    AM.GV = G->getGlobal();
15817721Speter    AM.Disp += G->getOffset();
15917721Speter    //AM.SymbolFlags = G->getTargetFlags();
16017721Speter  } else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(N0)) {
16117721Speter    AM.CP = CP->getConstVal();
16217721Speter    AM.Align = CP->getAlignment();
16317721Speter    AM.Disp += CP->getOffset();
16417721Speter    //AM.SymbolFlags = CP->getTargetFlags();
16517721Speter  } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(N0)) {
16617721Speter    AM.ES = S->getSymbol();
16717721Speter    //AM.SymbolFlags = S->getTargetFlags();
16817721Speter  } else if (JumpTableSDNode *J = dyn_cast<JumpTableSDNode>(N0)) {
16917721Speter    AM.JT = J->getIndex();
17017721Speter    //AM.SymbolFlags = J->getTargetFlags();
17117721Speter  } else {
17217721Speter    AM.BlockAddr = cast<BlockAddressSDNode>(N0)->getBlockAddress();
17317721Speter    //AM.SymbolFlags = cast<BlockAddressSDNode>(N0)->getTargetFlags();
17417721Speter  }
17517721Speter  return false;
17617721Speter}
17717721Speter
17817721Speter/// MatchAddressBase - Helper for MatchAddress. Add the specified node to the
17917721Speter/// specified addressing mode without any further recursion.
18017721Speterbool MSP430DAGToDAGISel::MatchAddressBase(SDValue N, MSP430ISelAddressMode &AM) {
18117721Speter  // Is the base register already occupied?
18217721Speter  if (AM.BaseType != MSP430ISelAddressMode::RegBase || AM.Base.Reg.getNode()) {
18317721Speter    // If so, we cannot select it.
18417721Speter    return true;
18517721Speter  }
18617721Speter
18717721Speter  // Default, generate it as a register.
18817721Speter  AM.BaseType = MSP430ISelAddressMode::RegBase;
18917721Speter  AM.Base.Reg = N;
19017721Speter  return false;
19117721Speter}
19217721Speter
19317721Speterbool MSP430DAGToDAGISel::MatchAddress(SDValue N, MSP430ISelAddressMode &AM) {
19417721Speter  DEBUG(errs() << "MatchAddress: "; AM.dump());
19517721Speter
19617721Speter  switch (N.getOpcode()) {
19717721Speter  default: break;
19817721Speter  case ISD::Constant: {
19917721Speter    uint64_t Val = cast<ConstantSDNode>(N)->getSExtValue();
20017721Speter    AM.Disp += Val;
20117721Speter    return false;
20217721Speter  }
20317721Speter
20417721Speter  case MSP430ISD::Wrapper:
20517721Speter    if (!MatchWrapper(N, AM))
20617721Speter      return false;
20717721Speter    break;
20817721Speter
20917721Speter  case ISD::FrameIndex:
21017721Speter    if (AM.BaseType == MSP430ISelAddressMode::RegBase
21117721Speter        && AM.Base.Reg.getNode() == 0) {
21217721Speter      AM.BaseType = MSP430ISelAddressMode::FrameIndexBase;
21317721Speter      AM.Base.FrameIndex = cast<FrameIndexSDNode>(N)->getIndex();
21417721Speter      return false;
21517721Speter    }
21617721Speter    break;
21717721Speter
21817721Speter  case ISD::ADD: {
21917721Speter    MSP430ISelAddressMode Backup = AM;
22017721Speter    if (!MatchAddress(N.getNode()->getOperand(0), AM) &&
22117721Speter        !MatchAddress(N.getNode()->getOperand(1), AM))
22217721Speter      return false;
22317721Speter    AM = Backup;
22417721Speter    if (!MatchAddress(N.getNode()->getOperand(1), AM) &&
22517721Speter        !MatchAddress(N.getNode()->getOperand(0), AM))
22617721Speter      return false;
22717721Speter    AM = Backup;
22817721Speter
22917721Speter    break;
23017721Speter  }
23117721Speter
23217721Speter  case ISD::OR:
23317721Speter    // Handle "X | C" as "X + C" iff X is known to have C bits clear.
23417721Speter    if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
23517721Speter      MSP430ISelAddressMode Backup = AM;
23617721Speter      uint64_t Offset = CN->getSExtValue();
23717721Speter      // Start with the LHS as an addr mode.
23817721Speter      if (!MatchAddress(N.getOperand(0), AM) &&
23917721Speter          // Address could not have picked a GV address for the displacement.
24017721Speter          AM.GV == NULL &&
24117721Speter          // Check to see if the LHS & C is zero.
24217721Speter          CurDAG->MaskedValueIsZero(N.getOperand(0), CN->getAPIntValue())) {
24317721Speter        AM.Disp += Offset;
24417721Speter        return false;
24517721Speter      }
24617721Speter      AM = Backup;
24717721Speter    }
24817721Speter    break;
24917721Speter  }
25017721Speter
25117721Speter  return MatchAddressBase(N, AM);
25217721Speter}
25317721Speter
25417721Speter/// SelectAddr - returns true if it is able pattern match an addressing mode.
25517721Speter/// It returns the operands which make up the maximal addressing mode it can
25617721Speter/// match by reference.
25717721Speterbool MSP430DAGToDAGISel::SelectAddr(SDNode *Op, SDValue N,
25817721Speter                                    SDValue &Base, SDValue &Disp) {
25917721Speter  MSP430ISelAddressMode AM;
26017721Speter
26117721Speter  if (MatchAddress(N, AM))
26217721Speter    return false;
26317721Speter
26417721Speter  EVT VT = N.getValueType();
26517721Speter  if (AM.BaseType == MSP430ISelAddressMode::RegBase) {
26617721Speter    if (!AM.Base.Reg.getNode())
26717721Speter      AM.Base.Reg = CurDAG->getRegister(0, VT);
26817721Speter  }
26917721Speter
27017721Speter  Base  = (AM.BaseType == MSP430ISelAddressMode::FrameIndexBase) ?
27117721Speter    CurDAG->getTargetFrameIndex(AM.Base.FrameIndex, TLI.getPointerTy()) :
27217721Speter    AM.Base.Reg;
27317721Speter
27417721Speter  if (AM.GV)
27517721Speter    Disp = CurDAG->getTargetGlobalAddress(AM.GV, MVT::i16, AM.Disp,
27617721Speter                                          0/*AM.SymbolFlags*/);
27717721Speter  else if (AM.CP)
27817721Speter    Disp = CurDAG->getTargetConstantPool(AM.CP, MVT::i16,
27917721Speter                                         AM.Align, AM.Disp, 0/*AM.SymbolFlags*/);
28017721Speter  else if (AM.ES)
28117721Speter    Disp = CurDAG->getTargetExternalSymbol(AM.ES, MVT::i16, 0/*AM.SymbolFlags*/);
28217721Speter  else if (AM.JT != -1)
28317721Speter    Disp = CurDAG->getTargetJumpTable(AM.JT, MVT::i16, 0/*AM.SymbolFlags*/);
28417721Speter  else if (AM.BlockAddr)
28517721Speter    Disp = CurDAG->getBlockAddress(AM.BlockAddr, MVT::i32,
28617721Speter                                   true, 0/*AM.SymbolFlags*/);
28717721Speter  else
28817721Speter    Disp = CurDAG->getTargetConstant(AM.Disp, MVT::i16);
28917721Speter
29017721Speter  return true;
29117721Speter}
29217721Speter
29317721Speterbool MSP430DAGToDAGISel::
29417721SpeterSelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
29517721Speter                             std::vector<SDValue> &OutOps) {
29617721Speter  SDValue Op0, Op1;
29717721Speter  switch (ConstraintCode) {
29817721Speter  default: return true;
29917721Speter  case 'm':   // memory
30017721Speter    if (!SelectAddr(Op.getNode(), Op, Op0, Op1))
30117721Speter      return true;
30217721Speter    break;
30317721Speter  }
30417721Speter
30517721Speter  OutOps.push_back(Op0);
30617721Speter  OutOps.push_back(Op1);
30717721Speter  return false;
30817721Speter}
30917721Speter
31017721Speterstatic bool isValidIndexedLoad(const LoadSDNode *LD) {
31117721Speter  ISD::MemIndexedMode AM = LD->getAddressingMode();
31217721Speter  if (AM != ISD::POST_INC || LD->getExtensionType() != ISD::NON_EXTLOAD)
31317721Speter    return false;
31417721Speter
31517721Speter  EVT VT = LD->getMemoryVT();
31617721Speter
31717721Speter  switch (VT.getSimpleVT().SimpleTy) {
31817721Speter  case MVT::i8:
31917721Speter    // Sanity check
32017721Speter    if (cast<ConstantSDNode>(LD->getOffset())->getZExtValue() != 1)
32117721Speter      return false;
32217721Speter
32317721Speter    break;
32417721Speter  case MVT::i16:
32517721Speter    // Sanity check
32617721Speter    if (cast<ConstantSDNode>(LD->getOffset())->getZExtValue() != 2)
32717721Speter      return false;
32817721Speter
32917721Speter    break;
33017721Speter  default:
33117721Speter    return false;
33217721Speter  }
33317721Speter
33417721Speter  return true;
33517721Speter}
33617721Speter
33717721SpeterSDNode *MSP430DAGToDAGISel::SelectIndexedLoad(SDNode *N) {
33817721Speter  LoadSDNode *LD = cast<LoadSDNode>(N);
33917721Speter  if (!isValidIndexedLoad(LD))
34017721Speter    return NULL;
34117721Speter
34217721Speter  MVT VT = LD->getMemoryVT().getSimpleVT();
34317721Speter
34417721Speter  unsigned Opcode = 0;
34517721Speter  switch (VT.SimpleTy) {
34617721Speter  case MVT::i8:
34717721Speter    Opcode = MSP430::MOV8rm_POST;
34817721Speter    break;
34917721Speter  case MVT::i16:
35017721Speter    Opcode = MSP430::MOV16rm_POST;
35117721Speter    break;
35217721Speter  default:
35317721Speter    return NULL;
35417721Speter  }
35517721Speter
35617721Speter   return CurDAG->getMachineNode(Opcode, N->getDebugLoc(),
35717721Speter                                 VT, MVT::i16, MVT::Other,
35817721Speter                                 LD->getBasePtr(), LD->getChain());
35917721Speter}
36017721Speter
36117721SpeterSDNode *MSP430DAGToDAGISel::SelectIndexedBinOp(SDNode *Op,
36217721Speter                                               SDValue N1, SDValue N2,
36317721Speter                                               unsigned Opc8, unsigned Opc16) {
36417721Speter  if (N1.getOpcode() == ISD::LOAD &&
36517721Speter      N1.hasOneUse() &&
36617721Speter      IsLegalToFold(N1, Op, Op, OptLevel)) {
36717721Speter    LoadSDNode *LD = cast<LoadSDNode>(N1);
36817721Speter    if (!isValidIndexedLoad(LD))
36917721Speter      return NULL;
37017721Speter
37117721Speter    MVT VT = LD->getMemoryVT().getSimpleVT();
37217721Speter    unsigned Opc = (VT == MVT::i16 ? Opc16 : Opc8);
37317721Speter    MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
37417721Speter    MemRefs0[0] = cast<MemSDNode>(N1)->getMemOperand();
37517721Speter    SDValue Ops0[] = { N2, LD->getBasePtr(), LD->getChain() };
37617721Speter    SDNode *ResNode =
37717721Speter      CurDAG->SelectNodeTo(Op, Opc,
37817721Speter                           VT, MVT::i16, MVT::Other,
37917721Speter                           Ops0, 3);
38017721Speter    cast<MachineSDNode>(ResNode)->setMemRefs(MemRefs0, MemRefs0 + 1);
38117721Speter    // Transfer chain.
38217721Speter    ReplaceUses(SDValue(N1.getNode(), 2), SDValue(ResNode, 2));
38317721Speter    // Transfer writeback.
38417721Speter    ReplaceUses(SDValue(N1.getNode(), 1), SDValue(ResNode, 1));
38517721Speter    return ResNode;
38617721Speter  }
38717721Speter
38817721Speter  return NULL;
38917721Speter}
39017721Speter
39117721Speter
39217721SpeterSDNode *MSP430DAGToDAGISel::Select(SDNode *Node) {
39317721Speter  DebugLoc dl = Node->getDebugLoc();
39417721Speter
39517721Speter  // Dump information about the Node being selected
39617721Speter  DEBUG(errs() << "Selecting: ");
39717721Speter  DEBUG(Node->dump(CurDAG));
39817721Speter  DEBUG(errs() << "\n");
39917721Speter
40017721Speter  // If we have a custom node, we already have selected!
40117721Speter  if (Node->isMachineOpcode()) {
40217721Speter    DEBUG(errs() << "== ";
40317721Speter          Node->dump(CurDAG);
40417721Speter          errs() << "\n");
40517721Speter    return NULL;
40617721Speter  }
40717721Speter
40817721Speter  // Few custom selection stuff.
40917721Speter  switch (Node->getOpcode()) {
41017721Speter  default: break;
41117721Speter  case ISD::FrameIndex: {
41217721Speter    assert(Node->getValueType(0) == MVT::i16);
41317721Speter    int FI = cast<FrameIndexSDNode>(Node)->getIndex();
41417721Speter    SDValue TFI = CurDAG->getTargetFrameIndex(FI, MVT::i16);
41517721Speter    if (Node->hasOneUse())
41617721Speter      return CurDAG->SelectNodeTo(Node, MSP430::ADD16ri, MVT::i16,
41717721Speter                                  TFI, CurDAG->getTargetConstant(0, MVT::i16));
41817721Speter    return CurDAG->getMachineNode(MSP430::ADD16ri, dl, MVT::i16,
41917721Speter                                  TFI, CurDAG->getTargetConstant(0, MVT::i16));
42017721Speter  }
42117721Speter  case ISD::LOAD:
42217721Speter    if (SDNode *ResNode = SelectIndexedLoad(Node))
42317721Speter      return ResNode;
42417721Speter    // Other cases are autogenerated.
42517721Speter    break;
42617721Speter  case ISD::ADD:
42717721Speter    if (SDNode *ResNode =
42817721Speter        SelectIndexedBinOp(Node,
42917721Speter                           Node->getOperand(0), Node->getOperand(1),
43017721Speter                           MSP430::ADD8rm_POST, MSP430::ADD16rm_POST))
43117721Speter      return ResNode;
43217721Speter    else if (SDNode *ResNode =
43317721Speter             SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0),
43417721Speter                                MSP430::ADD8rm_POST, MSP430::ADD16rm_POST))
43517721Speter      return ResNode;
43617721Speter
43717721Speter    // Other cases are autogenerated.
43817721Speter    break;
43917721Speter  case ISD::SUB:
44017721Speter    if (SDNode *ResNode =
44117721Speter        SelectIndexedBinOp(Node,
44217721Speter                           Node->getOperand(0), Node->getOperand(1),
44317721Speter                           MSP430::SUB8rm_POST, MSP430::SUB16rm_POST))
44417721Speter      return ResNode;
44517721Speter
44617721Speter    // Other cases are autogenerated.
44717721Speter    break;
44817721Speter  case ISD::AND:
44917721Speter    if (SDNode *ResNode =
45017721Speter        SelectIndexedBinOp(Node,
45117721Speter                           Node->getOperand(0), Node->getOperand(1),
45217721Speter                           MSP430::AND8rm_POST, MSP430::AND16rm_POST))
45317721Speter      return ResNode;
45417721Speter    else if (SDNode *ResNode =
45517721Speter             SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0),
45617721Speter                                MSP430::AND8rm_POST, MSP430::AND16rm_POST))
45717721Speter      return ResNode;
45817721Speter
45917721Speter    // Other cases are autogenerated.
46017721Speter    break;
46117721Speter  case ISD::OR:
46217721Speter    if (SDNode *ResNode =
46317721Speter        SelectIndexedBinOp(Node,
46417721Speter                           Node->getOperand(0), Node->getOperand(1),
46517721Speter                           MSP430::OR8rm_POST, MSP430::OR16rm_POST))
46617721Speter      return ResNode;
46717721Speter    else if (SDNode *ResNode =
46817721Speter             SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0),
46917721Speter                                MSP430::OR8rm_POST, MSP430::OR16rm_POST))
47017721Speter      return ResNode;
47117721Speter
47217721Speter    // Other cases are autogenerated.
47317721Speter    break;
47417721Speter  case ISD::XOR:
47517721Speter    if (SDNode *ResNode =
47617721Speter        SelectIndexedBinOp(Node,
47717721Speter                           Node->getOperand(0), Node->getOperand(1),
47817721Speter                           MSP430::XOR8rm_POST, MSP430::XOR16rm_POST))
47917721Speter      return ResNode;
48017721Speter    else if (SDNode *ResNode =
48117721Speter             SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0),
48217721Speter                                MSP430::XOR8rm_POST, MSP430::XOR16rm_POST))
48317721Speter      return ResNode;
48417721Speter
48517721Speter    // Other cases are autogenerated.
48617721Speter    break;
48717721Speter  }
48817721Speter
48917721Speter  // Select the default instruction
49017721Speter  SDNode *ResNode = SelectCode(Node);
49117721Speter
49217721Speter  DEBUG(errs() << "=> ");
49317721Speter  if (ResNode == NULL || ResNode == Node)
49417721Speter    DEBUG(Node->dump(CurDAG));
49517721Speter  else
49617721Speter    DEBUG(ResNode->dump(CurDAG));
49717721Speter  DEBUG(errs() << "\n");
49817721Speter
49917721Speter  return ResNode;
50017721Speter}
50117721Speter