137171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov//===-- MSP430ISelDAGToDAG.cpp - A dag to dag inst selector for MSP430 ----===//
237171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov//
337171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov//                     The LLVM Compiler Infrastructure
437171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov//
537171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov// This file is distributed under the University of Illinois Open Source
637171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov// License. See LICENSE.TXT for details.
737171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov//
837171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov//===----------------------------------------------------------------------===//
937171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov//
1037171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov// This file defines an instruction selector for the MSP430 target.
1137171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov//
1237171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov//===----------------------------------------------------------------------===//
1337171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov
1437171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov#include "MSP430.h"
1537171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov#include "MSP430TargetMachine.h"
1637171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov#include "llvm/DerivedTypes.h"
1737171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov#include "llvm/Function.h"
1837171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov#include "llvm/Intrinsics.h"
1937171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov#include "llvm/CallingConv.h"
2037171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov#include "llvm/Constants.h"
2137171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov#include "llvm/CodeGen/MachineFrameInfo.h"
2237171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov#include "llvm/CodeGen/MachineFunction.h"
2337171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov#include "llvm/CodeGen/MachineInstrBuilder.h"
2437171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov#include "llvm/CodeGen/MachineRegisterInfo.h"
2537171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov#include "llvm/CodeGen/SelectionDAG.h"
2637171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov#include "llvm/CodeGen/SelectionDAGISel.h"
2737171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov#include "llvm/Target/TargetLowering.h"
2837171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov#include "llvm/Support/Compiler.h"
2937171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov#include "llvm/Support/Debug.h"
304d9756a9843862edb9daddfaa0d8c78ac1c52b32Edwin Török#include "llvm/Support/ErrorHandling.h"
314d9756a9843862edb9daddfaa0d8c78ac1c52b32Edwin Török#include "llvm/Support/raw_ostream.h"
3237171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikovusing namespace llvm;
3337171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov
341c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikovnamespace {
351c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  struct MSP430ISelAddressMode {
361c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    enum {
371c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov      RegBase,
381c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov      FrameIndexBase
391c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    } BaseType;
401c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov
411c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    struct {            // This is really a union, discriminated by BaseType!
421c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov      SDValue Reg;
431c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov      int FrameIndex;
441c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    } Base;
451c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov
461c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    int16_t Disp;
4736c56d0353f1a9c4e878f509aff85a62e5087dd4Dan Gohman    const GlobalValue *GV;
4836c56d0353f1a9c4e878f509aff85a62e5087dd4Dan Gohman    const Constant *CP;
4936c56d0353f1a9c4e878f509aff85a62e5087dd4Dan Gohman    const BlockAddress *BlockAddr;
501c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    const char *ES;
511c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    int JT;
521c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    unsigned Align;    // CP alignment.
531c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov
541c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    MSP430ISelAddressMode()
551c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov      : BaseType(RegBase), Disp(0), GV(0), CP(0), BlockAddr(0),
561c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov        ES(0), JT(-1), Align(0) {
571c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    }
581c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov
591c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    bool hasSymbolicDisplacement() const {
601c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov      return GV != 0 || CP != 0 || ES != 0 || JT != -1;
611c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    }
621c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov
631c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    void dump() {
641c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov      errs() << "MSP430ISelAddressMode " << this << '\n';
65efb9350360fe13284f9162fec884d16590da206aAnton Korobeynikov      if (BaseType == RegBase && Base.Reg.getNode() != 0) {
661c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov        errs() << "Base.Reg ";
671c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov        Base.Reg.getNode()->dump();
68efb9350360fe13284f9162fec884d16590da206aAnton Korobeynikov      } else if (BaseType == FrameIndexBase) {
691c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov        errs() << " Base.FrameIndex " << Base.FrameIndex << '\n';
701c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov      }
711c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov      errs() << " Disp " << Disp << '\n';
721c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov      if (GV) {
731c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov        errs() << "GV ";
741c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov        GV->dump();
751c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov      } else if (CP) {
761c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov        errs() << " CP ";
771c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov        CP->dump();
781c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov        errs() << " Align" << Align << '\n';
791c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov      } else if (ES) {
801c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov        errs() << "ES ";
811c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov        errs() << ES << '\n';
821c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov      } else if (JT != -1)
831c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov        errs() << " JT" << JT << " Align" << Align << '\n';
841c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    }
851c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  };
861c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov}
871c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov
8837171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov/// MSP430DAGToDAGISel - MSP430 specific code to select MSP430 machine
8937171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov/// instructions for SelectionDAG operations.
9037171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov///
9137171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikovnamespace {
9237171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov  class MSP430DAGToDAGISel : public SelectionDAGISel {
93dbb121b1f19bf77e0bef8725d5ee42c1b8761cafDan Gohman    const MSP430TargetLowering &Lowering;
9437171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov    const MSP430Subtarget &Subtarget;
9537171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov
9637171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov  public:
970d370dcf2d8b7092355935d7d52e7236dd745345Anton Korobeynikov    MSP430DAGToDAGISel(MSP430TargetMachine &TM, CodeGenOpt::Level OptLevel)
980d370dcf2d8b7092355935d7d52e7236dd745345Anton Korobeynikov      : SelectionDAGISel(TM, OptLevel),
9937171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov        Lowering(*TM.getTargetLowering()),
10037171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov        Subtarget(*TM.getSubtargetImpl()) { }
10137171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov
10237171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov    virtual const char *getPassName() const {
10337171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov      return "MSP430 DAG->DAG Pattern Instruction Selection";
10437171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov    }
10537171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov
1061c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    bool MatchAddress(SDValue N, MSP430ISelAddressMode &AM);
1071c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    bool MatchWrapper(SDValue N, MSP430ISelAddressMode &AM);
1081c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    bool MatchAddressBase(SDValue N, MSP430ISelAddressMode &AM);
1091c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov
1109cbe2bc74aff10a95b2ee6ed6fb4a47dffee4751Anton Korobeynikov    virtual bool
1119cbe2bc74aff10a95b2ee6ed6fb4a47dffee4751Anton Korobeynikov    SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
1129cbe2bc74aff10a95b2ee6ed6fb4a47dffee4751Anton Korobeynikov                                 std::vector<SDValue> &OutOps);
1139cbe2bc74aff10a95b2ee6ed6fb4a47dffee4751Anton Korobeynikov
11437171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov    // Include the pieces autogenerated from the target description.
11537171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov  #include "MSP430GenDAGISel.inc"
11637171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov
11737171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov  private:
1185f082a7df38fa6d7b53c0d7baeca8d74f097d659Dan Gohman    SDNode *Select(SDNode *N);
1195f082a7df38fa6d7b53c0d7baeca8d74f097d659Dan Gohman    SDNode *SelectIndexedLoad(SDNode *Op);
1205f082a7df38fa6d7b53c0d7baeca8d74f097d659Dan Gohman    SDNode *SelectIndexedBinOp(SDNode *Op, SDValue N1, SDValue N2,
121a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov                               unsigned Opc8, unsigned Opc16);
122a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov
123ed3e0638525f4e5bc39d3ecc5d6282b7638ada94Chris Lattner    bool SelectAddr(SDValue Addr, SDValue &Base, SDValue &Disp);
12437171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov  };
12537171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov}  // end anonymous namespace
12637171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov
12737171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov/// createMSP430ISelDag - This pass converts a legalized DAG into a
12837171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov/// MSP430-specific DAG, ready for instruction scheduling.
12937171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov///
1300d370dcf2d8b7092355935d7d52e7236dd745345Anton KorobeynikovFunctionPass *llvm::createMSP430ISelDag(MSP430TargetMachine &TM,
1310d370dcf2d8b7092355935d7d52e7236dd745345Anton Korobeynikov                                        CodeGenOpt::Level OptLevel) {
1320d370dcf2d8b7092355935d7d52e7236dd745345Anton Korobeynikov  return new MSP430DAGToDAGISel(TM, OptLevel);
13337171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov}
13437171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov
1351c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov
1361c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov/// MatchWrapper - Try to match MSP430ISD::Wrapper node into an addressing mode.
1371c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov/// These wrap things that will resolve down into a symbol reference.  If no
1381c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov/// match is possible, this returns true, otherwise it returns false.
1391c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikovbool MSP430DAGToDAGISel::MatchWrapper(SDValue N, MSP430ISelAddressMode &AM) {
1401c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  // If the addressing mode already has a symbol as the displacement, we can
1411c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  // never match another symbol.
1421c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  if (AM.hasSymbolicDisplacement())
1439dbaeaa03759d55f35edaf98d6078d7076b99882Anton Korobeynikov    return true;
1441c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov
1451c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  SDValue N0 = N.getOperand(0);
1461c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov
1471c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(N0)) {
1481c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    AM.GV = G->getGlobal();
1491c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    AM.Disp += G->getOffset();
1501c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    //AM.SymbolFlags = G->getTargetFlags();
1511c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  } else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(N0)) {
1521c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    AM.CP = CP->getConstVal();
1531c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    AM.Align = CP->getAlignment();
1541c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    AM.Disp += CP->getOffset();
1551c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    //AM.SymbolFlags = CP->getTargetFlags();
1561c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(N0)) {
1571c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    AM.ES = S->getSymbol();
1581c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    //AM.SymbolFlags = S->getTargetFlags();
1591c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  } else if (JumpTableSDNode *J = dyn_cast<JumpTableSDNode>(N0)) {
1601c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    AM.JT = J->getIndex();
1611c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    //AM.SymbolFlags = J->getTargetFlags();
1621c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  } else {
1631c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    AM.BlockAddr = cast<BlockAddressSDNode>(N0)->getBlockAddress();
1641c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    //AM.SymbolFlags = cast<BlockAddressSDNode>(N0)->getTargetFlags();
1659dbaeaa03759d55f35edaf98d6078d7076b99882Anton Korobeynikov  }
1661c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  return false;
1671c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov}
1684c88f11c8739ff1395bc5b07b223eb84894d50e9Anton Korobeynikov
1691c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov/// MatchAddressBase - Helper for MatchAddress. Add the specified node to the
1701c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov/// specified addressing mode without any further recursion.
1711c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikovbool MSP430DAGToDAGISel::MatchAddressBase(SDValue N, MSP430ISelAddressMode &AM) {
1721c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  // Is the base register already occupied?
1731c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  if (AM.BaseType != MSP430ISelAddressMode::RegBase || AM.Base.Reg.getNode()) {
1741c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    // If so, we cannot select it.
1751c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    return true;
1761c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  }
1771c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov
1781c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  // Default, generate it as a register.
1791c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  AM.BaseType = MSP430ISelAddressMode::RegBase;
1801c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  AM.Base.Reg = N;
1811c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  return false;
1821c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov}
1831c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov
1841c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikovbool MSP430DAGToDAGISel::MatchAddress(SDValue N, MSP430ISelAddressMode &AM) {
185087340ec12cbd65e0e16e9ac9be194b3b57c8f2eChris Lattner  DEBUG(errs() << "MatchAddress: "; AM.dump());
1861c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov
1871c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  switch (N.getOpcode()) {
1881c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  default: break;
1891c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  case ISD::Constant: {
1901c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    uint64_t Val = cast<ConstantSDNode>(N)->getSExtValue();
1911c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    AM.Disp += Val;
1921c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    return false;
1931c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  }
1941c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov
1951c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  case MSP430ISD::Wrapper:
1961c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    if (!MatchWrapper(N, AM))
1971c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov      return false;
1981c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    break;
1991c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov
2001c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  case ISD::FrameIndex:
2011c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    if (AM.BaseType == MSP430ISelAddressMode::RegBase
2021c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov        && AM.Base.Reg.getNode() == 0) {
2031c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov      AM.BaseType = MSP430ISelAddressMode::FrameIndexBase;
2041c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov      AM.Base.FrameIndex = cast<FrameIndexSDNode>(N)->getIndex();
2051c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov      return false;
2064c88f11c8739ff1395bc5b07b223eb84894d50e9Anton Korobeynikov    }
2079841d21a31cbc34a0915671ac89116215568ace7Anton Korobeynikov    break;
2081c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov
2091c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  case ISD::ADD: {
2101c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    MSP430ISelAddressMode Backup = AM;
2111c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    if (!MatchAddress(N.getNode()->getOperand(0), AM) &&
2121c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov        !MatchAddress(N.getNode()->getOperand(1), AM))
2131c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov      return false;
2141c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    AM = Backup;
2151c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    if (!MatchAddress(N.getNode()->getOperand(1), AM) &&
2161c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov        !MatchAddress(N.getNode()->getOperand(0), AM))
2171c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov      return false;
2181c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    AM = Backup;
2191c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov
2201c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    break;
2211c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  }
2221c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov
2231c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  case ISD::OR:
2241c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    // Handle "X | C" as "X + C" iff X is known to have C bits clear.
2251c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
2261c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov      MSP430ISelAddressMode Backup = AM;
2271c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov      uint64_t Offset = CN->getSExtValue();
2281c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov      // Start with the LHS as an addr mode.
2291c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov      if (!MatchAddress(N.getOperand(0), AM) &&
2301c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov          // Address could not have picked a GV address for the displacement.
2311c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov          AM.GV == NULL &&
2321c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov          // Check to see if the LHS & C is zero.
2331c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov          CurDAG->MaskedValueIsZero(N.getOperand(0), CN->getAPIntValue())) {
2341c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov        AM.Disp += Offset;
2351c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov        return false;
2361c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov      }
2371c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov      AM = Backup;
2389841d21a31cbc34a0915671ac89116215568ace7Anton Korobeynikov    }
2399841d21a31cbc34a0915671ac89116215568ace7Anton Korobeynikov    break;
2401c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  }
2411c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov
2421c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  return MatchAddressBase(N, AM);
2431c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov}
2441c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov
2451c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov/// SelectAddr - returns true if it is able pattern match an addressing mode.
2461c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov/// It returns the operands which make up the maximal addressing mode it can
2471c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov/// match by reference.
248ed3e0638525f4e5bc39d3ecc5d6282b7638ada94Chris Lattnerbool MSP430DAGToDAGISel::SelectAddr(SDValue N,
2491c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov                                    SDValue &Base, SDValue &Disp) {
2501c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  MSP430ISelAddressMode AM;
2511c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov
2521c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  if (MatchAddress(N, AM))
2531c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    return false;
2541c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov
2551c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  EVT VT = N.getValueType();
2561c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  if (AM.BaseType == MSP430ISelAddressMode::RegBase) {
2571c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    if (!AM.Base.Reg.getNode())
2581c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov      AM.Base.Reg = CurDAG->getRegister(0, VT);
2591c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  }
2601c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov
2611c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  Base  = (AM.BaseType == MSP430ISelAddressMode::FrameIndexBase) ?
2621c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    CurDAG->getTargetFrameIndex(AM.Base.FrameIndex, TLI.getPointerTy()) :
2631c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    AM.Base.Reg;
2644c88f11c8739ff1395bc5b07b223eb84894d50e9Anton Korobeynikov
2651c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  if (AM.GV)
266ed3e0638525f4e5bc39d3ecc5d6282b7638ada94Chris Lattner    Disp = CurDAG->getTargetGlobalAddress(AM.GV, N->getDebugLoc(),
267de09e922a6a82ff48d31328606f691591ae8fa19Devang Patel                                          MVT::i16, AM.Disp,
2681c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov                                          0/*AM.SymbolFlags*/);
2691c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  else if (AM.CP)
2701c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    Disp = CurDAG->getTargetConstantPool(AM.CP, MVT::i16,
2711c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov                                         AM.Align, AM.Disp, 0/*AM.SymbolFlags*/);
2721c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  else if (AM.ES)
2731c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    Disp = CurDAG->getTargetExternalSymbol(AM.ES, MVT::i16, 0/*AM.SymbolFlags*/);
2741c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  else if (AM.JT != -1)
2751c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    Disp = CurDAG->getTargetJumpTable(AM.JT, MVT::i16, 0/*AM.SymbolFlags*/);
2761c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  else if (AM.BlockAddr)
2779b9d2a5f2053a53da30f4bc42f18df77646ca3a9Dan Gohman    Disp = CurDAG->getBlockAddress(AM.BlockAddr, MVT::i32,
2789b9d2a5f2053a53da30f4bc42f18df77646ca3a9Dan Gohman                                   true, 0/*AM.SymbolFlags*/);
2791c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov  else
2801c7e166ffb74e4504175767260bd1e23e35f98b7Anton Korobeynikov    Disp = CurDAG->getTargetConstant(AM.Disp, MVT::i16);
2814c88f11c8739ff1395bc5b07b223eb84894d50e9Anton Korobeynikov
2824c88f11c8739ff1395bc5b07b223eb84894d50e9Anton Korobeynikov  return true;
2834c88f11c8739ff1395bc5b07b223eb84894d50e9Anton Korobeynikov}
2844c88f11c8739ff1395bc5b07b223eb84894d50e9Anton Korobeynikov
2859cbe2bc74aff10a95b2ee6ed6fb4a47dffee4751Anton Korobeynikovbool MSP430DAGToDAGISel::
2869cbe2bc74aff10a95b2ee6ed6fb4a47dffee4751Anton KorobeynikovSelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
2879cbe2bc74aff10a95b2ee6ed6fb4a47dffee4751Anton Korobeynikov                             std::vector<SDValue> &OutOps) {
2889cbe2bc74aff10a95b2ee6ed6fb4a47dffee4751Anton Korobeynikov  SDValue Op0, Op1;
2899cbe2bc74aff10a95b2ee6ed6fb4a47dffee4751Anton Korobeynikov  switch (ConstraintCode) {
2909cbe2bc74aff10a95b2ee6ed6fb4a47dffee4751Anton Korobeynikov  default: return true;
2919cbe2bc74aff10a95b2ee6ed6fb4a47dffee4751Anton Korobeynikov  case 'm':   // memory
292ed3e0638525f4e5bc39d3ecc5d6282b7638ada94Chris Lattner    if (!SelectAddr(Op, Op0, Op1))
2939cbe2bc74aff10a95b2ee6ed6fb4a47dffee4751Anton Korobeynikov      return true;
2949cbe2bc74aff10a95b2ee6ed6fb4a47dffee4751Anton Korobeynikov    break;
2959cbe2bc74aff10a95b2ee6ed6fb4a47dffee4751Anton Korobeynikov  }
2969cbe2bc74aff10a95b2ee6ed6fb4a47dffee4751Anton Korobeynikov
2979cbe2bc74aff10a95b2ee6ed6fb4a47dffee4751Anton Korobeynikov  OutOps.push_back(Op0);
2989cbe2bc74aff10a95b2ee6ed6fb4a47dffee4751Anton Korobeynikov  OutOps.push_back(Op1);
2999cbe2bc74aff10a95b2ee6ed6fb4a47dffee4751Anton Korobeynikov  return false;
3009cbe2bc74aff10a95b2ee6ed6fb4a47dffee4751Anton Korobeynikov}
3014c88f11c8739ff1395bc5b07b223eb84894d50e9Anton Korobeynikov
302a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikovstatic bool isValidIndexedLoad(const LoadSDNode *LD) {
303a6d97be420bb6fe615998154f555b06be9cc1cf5Anton Korobeynikov  ISD::MemIndexedMode AM = LD->getAddressingMode();
304a6d97be420bb6fe615998154f555b06be9cc1cf5Anton Korobeynikov  if (AM != ISD::POST_INC || LD->getExtensionType() != ISD::NON_EXTLOAD)
305a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov    return false;
306a6d97be420bb6fe615998154f555b06be9cc1cf5Anton Korobeynikov
307a6d97be420bb6fe615998154f555b06be9cc1cf5Anton Korobeynikov  EVT VT = LD->getMemoryVT();
308a6d97be420bb6fe615998154f555b06be9cc1cf5Anton Korobeynikov
309a6d97be420bb6fe615998154f555b06be9cc1cf5Anton Korobeynikov  switch (VT.getSimpleVT().SimpleTy) {
310a6d97be420bb6fe615998154f555b06be9cc1cf5Anton Korobeynikov  case MVT::i8:
311a6d97be420bb6fe615998154f555b06be9cc1cf5Anton Korobeynikov    // Sanity check
312a6d97be420bb6fe615998154f555b06be9cc1cf5Anton Korobeynikov    if (cast<ConstantSDNode>(LD->getOffset())->getZExtValue() != 1)
313a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov      return false;
314a6d97be420bb6fe615998154f555b06be9cc1cf5Anton Korobeynikov
315a6d97be420bb6fe615998154f555b06be9cc1cf5Anton Korobeynikov    break;
316a6d97be420bb6fe615998154f555b06be9cc1cf5Anton Korobeynikov  case MVT::i16:
317a6d97be420bb6fe615998154f555b06be9cc1cf5Anton Korobeynikov    // Sanity check
318a6d97be420bb6fe615998154f555b06be9cc1cf5Anton Korobeynikov    if (cast<ConstantSDNode>(LD->getOffset())->getZExtValue() != 2)
319a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov      return false;
320a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov
321a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov    break;
322a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov  default:
323a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov    return false;
324a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov  }
325a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov
326a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov  return true;
327a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov}
328a6d97be420bb6fe615998154f555b06be9cc1cf5Anton Korobeynikov
3295f082a7df38fa6d7b53c0d7baeca8d74f097d659Dan GohmanSDNode *MSP430DAGToDAGISel::SelectIndexedLoad(SDNode *N) {
3305f082a7df38fa6d7b53c0d7baeca8d74f097d659Dan Gohman  LoadSDNode *LD = cast<LoadSDNode>(N);
331a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov  if (!isValidIndexedLoad(LD))
332a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov    return NULL;
333a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov
334a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov  MVT VT = LD->getMemoryVT().getSimpleVT();
335a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov
336a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov  unsigned Opcode = 0;
337a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov  switch (VT.SimpleTy) {
338a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov  case MVT::i8:
339a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov    Opcode = MSP430::MOV8rm_POST;
340a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov    break;
341a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov  case MVT::i16:
342a6d97be420bb6fe615998154f555b06be9cc1cf5Anton Korobeynikov    Opcode = MSP430::MOV16rm_POST;
343a6d97be420bb6fe615998154f555b06be9cc1cf5Anton Korobeynikov    break;
344a6d97be420bb6fe615998154f555b06be9cc1cf5Anton Korobeynikov  default:
345a6d97be420bb6fe615998154f555b06be9cc1cf5Anton Korobeynikov    return NULL;
346a6d97be420bb6fe615998154f555b06be9cc1cf5Anton Korobeynikov  }
347a6d97be420bb6fe615998154f555b06be9cc1cf5Anton Korobeynikov
3485f082a7df38fa6d7b53c0d7baeca8d74f097d659Dan Gohman   return CurDAG->getMachineNode(Opcode, N->getDebugLoc(),
349a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov                                 VT, MVT::i16, MVT::Other,
350a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov                                 LD->getBasePtr(), LD->getChain());
351a6d97be420bb6fe615998154f555b06be9cc1cf5Anton Korobeynikov}
352a6d97be420bb6fe615998154f555b06be9cc1cf5Anton Korobeynikov
3535f082a7df38fa6d7b53c0d7baeca8d74f097d659Dan GohmanSDNode *MSP430DAGToDAGISel::SelectIndexedBinOp(SDNode *Op,
354a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov                                               SDValue N1, SDValue N2,
355a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov                                               unsigned Opc8, unsigned Opc16) {
356a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov  if (N1.getOpcode() == ISD::LOAD &&
357a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov      N1.hasOneUse() &&
358dbb121b1f19bf77e0bef8725d5ee42c1b8761cafDan Gohman      IsLegalToFold(N1, Op, Op, OptLevel)) {
359a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov    LoadSDNode *LD = cast<LoadSDNode>(N1);
360a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov    if (!isValidIndexedLoad(LD))
361a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov      return NULL;
362a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov
363a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov    MVT VT = LD->getMemoryVT().getSimpleVT();
364a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov    unsigned Opc = (VT == MVT::i16 ? Opc16 : Opc8);
365a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov    MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
366a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov    MemRefs0[0] = cast<MemSDNode>(N1)->getMemOperand();
367a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov    SDValue Ops0[] = { N2, LD->getBasePtr(), LD->getChain() };
368a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov    SDNode *ResNode =
3695f082a7df38fa6d7b53c0d7baeca8d74f097d659Dan Gohman      CurDAG->SelectNodeTo(Op, Opc,
370a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov                           VT, MVT::i16, MVT::Other,
371a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov                           Ops0, 3);
372a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov    cast<MachineSDNode>(ResNode)->setMemRefs(MemRefs0, MemRefs0 + 1);
373fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov    // Transfer chain.
374fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov    ReplaceUses(SDValue(N1.getNode(), 2), SDValue(ResNode, 2));
375fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov    // Transfer writeback.
376fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov    ReplaceUses(SDValue(N1.getNode(), 1), SDValue(ResNode, 1));
377a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov    return ResNode;
378a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov  }
379a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov
380a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov  return NULL;
381a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov}
382a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov
383a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov
3845f082a7df38fa6d7b53c0d7baeca8d74f097d659Dan GohmanSDNode *MSP430DAGToDAGISel::Select(SDNode *Node) {
3855f082a7df38fa6d7b53c0d7baeca8d74f097d659Dan Gohman  DebugLoc dl = Node->getDebugLoc();
38681e1f97bd3da47ff1b0cb85336a104a7a654f310Anton Korobeynikov
38781e1f97bd3da47ff1b0cb85336a104a7a654f310Anton Korobeynikov  // Dump information about the Node being selected
3886411e3e62ea9dfe23f5fa24b9d6a84da7ec70a98Chris Lattner  DEBUG(errs() << "Selecting: ");
38981e1f97bd3da47ff1b0cb85336a104a7a654f310Anton Korobeynikov  DEBUG(Node->dump(CurDAG));
3902c6014b7beb12b2eb1f2487d3b52ebea13b7f58eChris Lattner  DEBUG(errs() << "\n");
39181e1f97bd3da47ff1b0cb85336a104a7a654f310Anton Korobeynikov
39281e1f97bd3da47ff1b0cb85336a104a7a654f310Anton Korobeynikov  // If we have a custom node, we already have selected!
39381e1f97bd3da47ff1b0cb85336a104a7a654f310Anton Korobeynikov  if (Node->isMachineOpcode()) {
3946411e3e62ea9dfe23f5fa24b9d6a84da7ec70a98Chris Lattner    DEBUG(errs() << "== ";
3952c6014b7beb12b2eb1f2487d3b52ebea13b7f58eChris Lattner          Node->dump(CurDAG);
3962c6014b7beb12b2eb1f2487d3b52ebea13b7f58eChris Lattner          errs() << "\n");
39781e1f97bd3da47ff1b0cb85336a104a7a654f310Anton Korobeynikov    return NULL;
39881e1f97bd3da47ff1b0cb85336a104a7a654f310Anton Korobeynikov  }
39981e1f97bd3da47ff1b0cb85336a104a7a654f310Anton Korobeynikov
4003c10ef5a963c736849a7bb453238ede34be9eb77Anton Korobeynikov  // Few custom selection stuff.
4013c10ef5a963c736849a7bb453238ede34be9eb77Anton Korobeynikov  switch (Node->getOpcode()) {
4023c10ef5a963c736849a7bb453238ede34be9eb77Anton Korobeynikov  default: break;
4033c10ef5a963c736849a7bb453238ede34be9eb77Anton Korobeynikov  case ISD::FrameIndex: {
4045f082a7df38fa6d7b53c0d7baeca8d74f097d659Dan Gohman    assert(Node->getValueType(0) == MVT::i16);
4053c10ef5a963c736849a7bb453238ede34be9eb77Anton Korobeynikov    int FI = cast<FrameIndexSDNode>(Node)->getIndex();
40636e3a6e235ee8b21eba777686b4508f71248b869Owen Anderson    SDValue TFI = CurDAG->getTargetFrameIndex(FI, MVT::i16);
4073c10ef5a963c736849a7bb453238ede34be9eb77Anton Korobeynikov    if (Node->hasOneUse())
40836e3a6e235ee8b21eba777686b4508f71248b869Owen Anderson      return CurDAG->SelectNodeTo(Node, MSP430::ADD16ri, MVT::i16,
40936e3a6e235ee8b21eba777686b4508f71248b869Owen Anderson                                  TFI, CurDAG->getTargetConstant(0, MVT::i16));
41061fda0d889b3578fe435455679182c231a649aacDan Gohman    return CurDAG->getMachineNode(MSP430::ADD16ri, dl, MVT::i16,
41161fda0d889b3578fe435455679182c231a649aacDan Gohman                                  TFI, CurDAG->getTargetConstant(0, MVT::i16));
4123c10ef5a963c736849a7bb453238ede34be9eb77Anton Korobeynikov  }
413a6d97be420bb6fe615998154f555b06be9cc1cf5Anton Korobeynikov  case ISD::LOAD:
4145f082a7df38fa6d7b53c0d7baeca8d74f097d659Dan Gohman    if (SDNode *ResNode = SelectIndexedLoad(Node))
415a6d97be420bb6fe615998154f555b06be9cc1cf5Anton Korobeynikov      return ResNode;
416a6d97be420bb6fe615998154f555b06be9cc1cf5Anton Korobeynikov    // Other cases are autogenerated.
417a6d97be420bb6fe615998154f555b06be9cc1cf5Anton Korobeynikov    break;
418fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov  case ISD::ADD:
419fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov    if (SDNode *ResNode =
4205f082a7df38fa6d7b53c0d7baeca8d74f097d659Dan Gohman        SelectIndexedBinOp(Node,
4215f082a7df38fa6d7b53c0d7baeca8d74f097d659Dan Gohman                           Node->getOperand(0), Node->getOperand(1),
422fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov                           MSP430::ADD8rm_POST, MSP430::ADD16rm_POST))
423fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov      return ResNode;
424fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov    else if (SDNode *ResNode =
4255f082a7df38fa6d7b53c0d7baeca8d74f097d659Dan Gohman             SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0),
426fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov                                MSP430::ADD8rm_POST, MSP430::ADD16rm_POST))
427fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov      return ResNode;
428fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov
429fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov    // Other cases are autogenerated.
430fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov    break;
431fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov  case ISD::SUB:
432fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov    if (SDNode *ResNode =
4335f082a7df38fa6d7b53c0d7baeca8d74f097d659Dan Gohman        SelectIndexedBinOp(Node,
4345f082a7df38fa6d7b53c0d7baeca8d74f097d659Dan Gohman                           Node->getOperand(0), Node->getOperand(1),
435fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov                           MSP430::SUB8rm_POST, MSP430::SUB16rm_POST))
436fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov      return ResNode;
437fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov
438fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov    // Other cases are autogenerated.
439fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov    break;
440fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov  case ISD::AND:
441fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov    if (SDNode *ResNode =
4425f082a7df38fa6d7b53c0d7baeca8d74f097d659Dan Gohman        SelectIndexedBinOp(Node,
4435f082a7df38fa6d7b53c0d7baeca8d74f097d659Dan Gohman                           Node->getOperand(0), Node->getOperand(1),
444fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov                           MSP430::AND8rm_POST, MSP430::AND16rm_POST))
445fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov      return ResNode;
446fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov    else if (SDNode *ResNode =
4475f082a7df38fa6d7b53c0d7baeca8d74f097d659Dan Gohman             SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0),
448fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov                                MSP430::AND8rm_POST, MSP430::AND16rm_POST))
449fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov      return ResNode;
450fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov
451fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov    // Other cases are autogenerated.
452fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov    break;
453fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov  case ISD::OR:
454fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov    if (SDNode *ResNode =
4555f082a7df38fa6d7b53c0d7baeca8d74f097d659Dan Gohman        SelectIndexedBinOp(Node,
4565f082a7df38fa6d7b53c0d7baeca8d74f097d659Dan Gohman                           Node->getOperand(0), Node->getOperand(1),
457fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov                           MSP430::OR8rm_POST, MSP430::OR16rm_POST))
458fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov      return ResNode;
459fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov    else if (SDNode *ResNode =
4605f082a7df38fa6d7b53c0d7baeca8d74f097d659Dan Gohman             SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0),
461fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov                                MSP430::OR8rm_POST, MSP430::OR16rm_POST))
462fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov      return ResNode;
463fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov
464fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov    // Other cases are autogenerated.
465fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov    break;
466fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov  case ISD::XOR:
467fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov    if (SDNode *ResNode =
4685f082a7df38fa6d7b53c0d7baeca8d74f097d659Dan Gohman        SelectIndexedBinOp(Node,
4695f082a7df38fa6d7b53c0d7baeca8d74f097d659Dan Gohman                           Node->getOperand(0), Node->getOperand(1),
470fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov                           MSP430::XOR8rm_POST, MSP430::XOR16rm_POST))
471fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov      return ResNode;
472fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov    else if (SDNode *ResNode =
4735f082a7df38fa6d7b53c0d7baeca8d74f097d659Dan Gohman             SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0),
474fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov                                MSP430::XOR8rm_POST, MSP430::XOR16rm_POST))
475fc5c66b384e5ac8089737a40b97a02ae32176142Anton Korobeynikov      return ResNode;
476a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov
477a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov    // Other cases are autogenerated.
478a0e695bd1f1afe129a7e294b02cdba45629f0c9cAnton Korobeynikov    break;
4793c10ef5a963c736849a7bb453238ede34be9eb77Anton Korobeynikov  }
48081e1f97bd3da47ff1b0cb85336a104a7a654f310Anton Korobeynikov
48181e1f97bd3da47ff1b0cb85336a104a7a654f310Anton Korobeynikov  // Select the default instruction
4825f082a7df38fa6d7b53c0d7baeca8d74f097d659Dan Gohman  SDNode *ResNode = SelectCode(Node);
48381e1f97bd3da47ff1b0cb85336a104a7a654f310Anton Korobeynikov
4846411e3e62ea9dfe23f5fa24b9d6a84da7ec70a98Chris Lattner  DEBUG(errs() << "=> ");
4855f082a7df38fa6d7b53c0d7baeca8d74f097d659Dan Gohman  if (ResNode == NULL || ResNode == Node)
4865f082a7df38fa6d7b53c0d7baeca8d74f097d659Dan Gohman    DEBUG(Node->dump(CurDAG));
48781e1f97bd3da47ff1b0cb85336a104a7a654f310Anton Korobeynikov  else
48881e1f97bd3da47ff1b0cb85336a104a7a654f310Anton Korobeynikov    DEBUG(ResNode->dump(CurDAG));
4892c6014b7beb12b2eb1f2487d3b52ebea13b7f58eChris Lattner  DEBUG(errs() << "\n");
49081e1f97bd3da47ff1b0cb85336a104a7a654f310Anton Korobeynikov
49181e1f97bd3da47ff1b0cb85336a104a7a654f310Anton Korobeynikov  return ResNode;
49237171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov}
493