MSP430ISelDAGToDAG.cpp revision 61fda0d889b3578fe435455679182c231a649aac
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 "MSP430ISelLowering.h"
1637171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov#include "MSP430TargetMachine.h"
1737171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov#include "llvm/DerivedTypes.h"
1837171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov#include "llvm/Function.h"
1937171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov#include "llvm/Intrinsics.h"
2037171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov#include "llvm/CallingConv.h"
2137171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov#include "llvm/Constants.h"
2237171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov#include "llvm/CodeGen/MachineFrameInfo.h"
2337171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov#include "llvm/CodeGen/MachineFunction.h"
2437171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov#include "llvm/CodeGen/MachineInstrBuilder.h"
2537171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov#include "llvm/CodeGen/MachineRegisterInfo.h"
2637171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov#include "llvm/CodeGen/SelectionDAG.h"
2737171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov#include "llvm/CodeGen/SelectionDAGISel.h"
2837171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov#include "llvm/Target/TargetLowering.h"
2937171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov#include "llvm/Support/Compiler.h"
3037171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov#include "llvm/Support/Debug.h"
314d9756a9843862edb9daddfaa0d8c78ac1c52b32Edwin Török#include "llvm/Support/ErrorHandling.h"
324d9756a9843862edb9daddfaa0d8c78ac1c52b32Edwin Török#include "llvm/Support/raw_ostream.h"
3337171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikovusing namespace llvm;
3437171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov
3537171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov/// MSP430DAGToDAGISel - MSP430 specific code to select MSP430 machine
3637171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov/// instructions for SelectionDAG operations.
3737171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov///
3837171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikovnamespace {
3937171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov  class MSP430DAGToDAGISel : public SelectionDAGISel {
4037171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov    MSP430TargetLowering &Lowering;
4137171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov    const MSP430Subtarget &Subtarget;
4237171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov
4337171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov  public:
440d370dcf2d8b7092355935d7d52e7236dd745345Anton Korobeynikov    MSP430DAGToDAGISel(MSP430TargetMachine &TM, CodeGenOpt::Level OptLevel)
450d370dcf2d8b7092355935d7d52e7236dd745345Anton Korobeynikov      : SelectionDAGISel(TM, OptLevel),
4637171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov        Lowering(*TM.getTargetLowering()),
4737171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov        Subtarget(*TM.getSubtargetImpl()) { }
4837171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov
4937171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov    virtual void InstructionSelect();
5037171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov
5137171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov    virtual const char *getPassName() const {
5237171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov      return "MSP430 DAG->DAG Pattern Instruction Selection";
5337171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov    }
5437171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov
5537171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov    // Include the pieces autogenerated from the target description.
5637171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov  #include "MSP430GenDAGISel.inc"
5737171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov
5837171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov  private:
5937171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov    SDNode *Select(SDValue Op);
60a6e3669f02a049e1fc0e5732d5ffbbe4a19027fdAnton Korobeynikov    bool SelectAddr(SDValue Op, SDValue Addr, SDValue &Base, SDValue &Disp);
6181e1f97bd3da47ff1b0cb85336a104a7a654f310Anton Korobeynikov
6281e1f97bd3da47ff1b0cb85336a104a7a654f310Anton Korobeynikov  #ifndef NDEBUG
6381e1f97bd3da47ff1b0cb85336a104a7a654f310Anton Korobeynikov    unsigned Indent;
6481e1f97bd3da47ff1b0cb85336a104a7a654f310Anton Korobeynikov  #endif
6537171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov  };
6637171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov}  // end anonymous namespace
6737171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov
6837171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov/// createMSP430ISelDag - This pass converts a legalized DAG into a
6937171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov/// MSP430-specific DAG, ready for instruction scheduling.
7037171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov///
710d370dcf2d8b7092355935d7d52e7236dd745345Anton KorobeynikovFunctionPass *llvm::createMSP430ISelDag(MSP430TargetMachine &TM,
720d370dcf2d8b7092355935d7d52e7236dd745345Anton Korobeynikov                                        CodeGenOpt::Level OptLevel) {
730d370dcf2d8b7092355935d7d52e7236dd745345Anton Korobeynikov  return new MSP430DAGToDAGISel(TM, OptLevel);
7437171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov}
7537171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov
760a4985b79ec879d0267b6e7d64fc551249c086c8Anton Korobeynikov// FIXME: This is pretty dummy routine and needs to be rewritten in the future.
774c88f11c8739ff1395bc5b07b223eb84894d50e9Anton Korobeynikovbool MSP430DAGToDAGISel::SelectAddr(SDValue Op, SDValue Addr,
78a6e3669f02a049e1fc0e5732d5ffbbe4a19027fdAnton Korobeynikov                                    SDValue &Base, SDValue &Disp) {
799dbaeaa03759d55f35edaf98d6078d7076b99882Anton Korobeynikov  // Try to match frame address first.
809dbaeaa03759d55f35edaf98d6078d7076b99882Anton Korobeynikov  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
8136e3a6e235ee8b21eba777686b4508f71248b869Owen Anderson    Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i16);
8236e3a6e235ee8b21eba777686b4508f71248b869Owen Anderson    Disp = CurDAG->getTargetConstant(0, MVT::i16);
839dbaeaa03759d55f35edaf98d6078d7076b99882Anton Korobeynikov    return true;
849dbaeaa03759d55f35edaf98d6078d7076b99882Anton Korobeynikov  }
854c88f11c8739ff1395bc5b07b223eb84894d50e9Anton Korobeynikov
869841d21a31cbc34a0915671ac89116215568ace7Anton Korobeynikov  switch (Addr.getOpcode()) {
879841d21a31cbc34a0915671ac89116215568ace7Anton Korobeynikov  case ISD::ADD:
8876f578d8a41309e9a74e1c87476b9a19693cbb93Anton Korobeynikov   // Operand is a result from ADD with constant operand which fits into i16.
8976f578d8a41309e9a74e1c87476b9a19693cbb93Anton Korobeynikov   if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
904c88f11c8739ff1395bc5b07b223eb84894d50e9Anton Korobeynikov      uint64_t CVal = CN->getZExtValue();
914c88f11c8739ff1395bc5b07b223eb84894d50e9Anton Korobeynikov      // Offset should fit into 16 bits.
924c88f11c8739ff1395bc5b07b223eb84894d50e9Anton Korobeynikov      if (((CVal << 48) >> 48) == CVal) {
939dbaeaa03759d55f35edaf98d6078d7076b99882Anton Korobeynikov        SDValue N0 = Addr.getOperand(0);
949dbaeaa03759d55f35edaf98d6078d7076b99882Anton Korobeynikov        if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(N0))
9536e3a6e235ee8b21eba777686b4508f71248b869Owen Anderson          Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i16);
969dbaeaa03759d55f35edaf98d6078d7076b99882Anton Korobeynikov        else
979dbaeaa03759d55f35edaf98d6078d7076b99882Anton Korobeynikov          Base = N0;
984c88f11c8739ff1395bc5b07b223eb84894d50e9Anton Korobeynikov
9936e3a6e235ee8b21eba777686b4508f71248b869Owen Anderson        Disp = CurDAG->getTargetConstant(CVal, MVT::i16);
1004c88f11c8739ff1395bc5b07b223eb84894d50e9Anton Korobeynikov        return true;
1014c88f11c8739ff1395bc5b07b223eb84894d50e9Anton Korobeynikov      }
1024c88f11c8739ff1395bc5b07b223eb84894d50e9Anton Korobeynikov    }
1039841d21a31cbc34a0915671ac89116215568ace7Anton Korobeynikov    break;
1049841d21a31cbc34a0915671ac89116215568ace7Anton Korobeynikov  case MSP430ISD::Wrapper:
1059841d21a31cbc34a0915671ac89116215568ace7Anton Korobeynikov    SDValue N0 = Addr.getOperand(0);
1069841d21a31cbc34a0915671ac89116215568ace7Anton Korobeynikov    if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(N0)) {
107a6e3669f02a049e1fc0e5732d5ffbbe4a19027fdAnton Korobeynikov      Base = CurDAG->getTargetGlobalAddress(G->getGlobal(),
10836e3a6e235ee8b21eba777686b4508f71248b869Owen Anderson                                            MVT::i16, G->getOffset());
10936e3a6e235ee8b21eba777686b4508f71248b869Owen Anderson      Disp = CurDAG->getTargetConstant(0, MVT::i16);
1100a4985b79ec879d0267b6e7d64fc551249c086c8Anton Korobeynikov      return true;
111165bbe3b7517003c363e54f3187f5dcc1218e2ddAnton Korobeynikov    } else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(N0)) {
11236e3a6e235ee8b21eba777686b4508f71248b869Owen Anderson      Base = CurDAG->getTargetExternalSymbol(E->getSymbol(), MVT::i16);
11336e3a6e235ee8b21eba777686b4508f71248b869Owen Anderson      Disp = CurDAG->getTargetConstant(0, MVT::i16);
1149841d21a31cbc34a0915671ac89116215568ace7Anton Korobeynikov    }
1159841d21a31cbc34a0915671ac89116215568ace7Anton Korobeynikov    break;
1169841d21a31cbc34a0915671ac89116215568ace7Anton Korobeynikov  };
1174c88f11c8739ff1395bc5b07b223eb84894d50e9Anton Korobeynikov
118a6e3669f02a049e1fc0e5732d5ffbbe4a19027fdAnton Korobeynikov  Base = Addr;
11936e3a6e235ee8b21eba777686b4508f71248b869Owen Anderson  Disp = CurDAG->getTargetConstant(0, MVT::i16);
1204c88f11c8739ff1395bc5b07b223eb84894d50e9Anton Korobeynikov
1214c88f11c8739ff1395bc5b07b223eb84894d50e9Anton Korobeynikov  return true;
1224c88f11c8739ff1395bc5b07b223eb84894d50e9Anton Korobeynikov}
1234c88f11c8739ff1395bc5b07b223eb84894d50e9Anton Korobeynikov
1244c88f11c8739ff1395bc5b07b223eb84894d50e9Anton Korobeynikov
1254c88f11c8739ff1395bc5b07b223eb84894d50e9Anton Korobeynikov
12637171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov/// InstructionSelect - This callback is invoked by
12737171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
12810a5a3c82145edc6fe8e9b030b0ccb27b625adb1Anton Korobeynikovvoid MSP430DAGToDAGISel::InstructionSelect() {
12937171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov  DEBUG(BB->dump());
13037171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov
1317a872e95a74b53a5360b559e4096dcb6753263daAnton Korobeynikov  // Codegen the basic block.
1322c6014b7beb12b2eb1f2487d3b52ebea13b7f58eChris Lattner  DEBUG(errs() << "===== Instruction selection begins:\n");
13333b2663488b0f8f188c1a6003faabd5ee89f7749Daniel Dunbar  DEBUG(Indent = 0);
13437171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov  SelectRoot(*CurDAG);
1352c6014b7beb12b2eb1f2487d3b52ebea13b7f58eChris Lattner  DEBUG(errs() << "===== Instruction selection ends:\n");
13637171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov
13737171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov  CurDAG->RemoveDeadNodes();
13837171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov}
13937171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov
14037171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton KorobeynikovSDNode *MSP430DAGToDAGISel::Select(SDValue Op) {
14181e1f97bd3da47ff1b0cb85336a104a7a654f310Anton Korobeynikov  SDNode *Node = Op.getNode();
1423c10ef5a963c736849a7bb453238ede34be9eb77Anton Korobeynikov  DebugLoc dl = Op.getDebugLoc();
14381e1f97bd3da47ff1b0cb85336a104a7a654f310Anton Korobeynikov
14481e1f97bd3da47ff1b0cb85336a104a7a654f310Anton Korobeynikov  // Dump information about the Node being selected
1452c6014b7beb12b2eb1f2487d3b52ebea13b7f58eChris Lattner  DEBUG(errs().indent(Indent) << "Selecting: ");
14681e1f97bd3da47ff1b0cb85336a104a7a654f310Anton Korobeynikov  DEBUG(Node->dump(CurDAG));
1472c6014b7beb12b2eb1f2487d3b52ebea13b7f58eChris Lattner  DEBUG(errs() << "\n");
14833b2663488b0f8f188c1a6003faabd5ee89f7749Daniel Dunbar  DEBUG(Indent += 2);
14981e1f97bd3da47ff1b0cb85336a104a7a654f310Anton Korobeynikov
15081e1f97bd3da47ff1b0cb85336a104a7a654f310Anton Korobeynikov  // If we have a custom node, we already have selected!
15181e1f97bd3da47ff1b0cb85336a104a7a654f310Anton Korobeynikov  if (Node->isMachineOpcode()) {
1522c6014b7beb12b2eb1f2487d3b52ebea13b7f58eChris Lattner    DEBUG(errs().indent(Indent-2) << "== ";
1532c6014b7beb12b2eb1f2487d3b52ebea13b7f58eChris Lattner          Node->dump(CurDAG);
1542c6014b7beb12b2eb1f2487d3b52ebea13b7f58eChris Lattner          errs() << "\n");
15533b2663488b0f8f188c1a6003faabd5ee89f7749Daniel Dunbar    DEBUG(Indent -= 2);
15681e1f97bd3da47ff1b0cb85336a104a7a654f310Anton Korobeynikov    return NULL;
15781e1f97bd3da47ff1b0cb85336a104a7a654f310Anton Korobeynikov  }
15881e1f97bd3da47ff1b0cb85336a104a7a654f310Anton Korobeynikov
1593c10ef5a963c736849a7bb453238ede34be9eb77Anton Korobeynikov  // Few custom selection stuff.
1603c10ef5a963c736849a7bb453238ede34be9eb77Anton Korobeynikov  switch (Node->getOpcode()) {
1613c10ef5a963c736849a7bb453238ede34be9eb77Anton Korobeynikov  default: break;
1623c10ef5a963c736849a7bb453238ede34be9eb77Anton Korobeynikov  case ISD::FrameIndex: {
16336e3a6e235ee8b21eba777686b4508f71248b869Owen Anderson    assert(Op.getValueType() == MVT::i16);
1643c10ef5a963c736849a7bb453238ede34be9eb77Anton Korobeynikov    int FI = cast<FrameIndexSDNode>(Node)->getIndex();
16536e3a6e235ee8b21eba777686b4508f71248b869Owen Anderson    SDValue TFI = CurDAG->getTargetFrameIndex(FI, MVT::i16);
1663c10ef5a963c736849a7bb453238ede34be9eb77Anton Korobeynikov    if (Node->hasOneUse())
16736e3a6e235ee8b21eba777686b4508f71248b869Owen Anderson      return CurDAG->SelectNodeTo(Node, MSP430::ADD16ri, MVT::i16,
16836e3a6e235ee8b21eba777686b4508f71248b869Owen Anderson                                  TFI, CurDAG->getTargetConstant(0, MVT::i16));
16961fda0d889b3578fe435455679182c231a649aacDan Gohman    return CurDAG->getMachineNode(MSP430::ADD16ri, dl, MVT::i16,
17061fda0d889b3578fe435455679182c231a649aacDan Gohman                                  TFI, CurDAG->getTargetConstant(0, MVT::i16));
1713c10ef5a963c736849a7bb453238ede34be9eb77Anton Korobeynikov  }
1723c10ef5a963c736849a7bb453238ede34be9eb77Anton Korobeynikov  }
17381e1f97bd3da47ff1b0cb85336a104a7a654f310Anton Korobeynikov
17481e1f97bd3da47ff1b0cb85336a104a7a654f310Anton Korobeynikov  // Select the default instruction
17581e1f97bd3da47ff1b0cb85336a104a7a654f310Anton Korobeynikov  SDNode *ResNode = SelectCode(Op);
17681e1f97bd3da47ff1b0cb85336a104a7a654f310Anton Korobeynikov
1772c6014b7beb12b2eb1f2487d3b52ebea13b7f58eChris Lattner  DEBUG(errs() << std::string(Indent-2, ' ') << "=> ");
17881e1f97bd3da47ff1b0cb85336a104a7a654f310Anton Korobeynikov  if (ResNode == NULL || ResNode == Op.getNode())
17981e1f97bd3da47ff1b0cb85336a104a7a654f310Anton Korobeynikov    DEBUG(Op.getNode()->dump(CurDAG));
18081e1f97bd3da47ff1b0cb85336a104a7a654f310Anton Korobeynikov  else
18181e1f97bd3da47ff1b0cb85336a104a7a654f310Anton Korobeynikov    DEBUG(ResNode->dump(CurDAG));
1822c6014b7beb12b2eb1f2487d3b52ebea13b7f58eChris Lattner  DEBUG(errs() << "\n");
18333b2663488b0f8f188c1a6003faabd5ee89f7749Daniel Dunbar  DEBUG(Indent -= 2);
18481e1f97bd3da47ff1b0cb85336a104a7a654f310Anton Korobeynikov
18581e1f97bd3da47ff1b0cb85336a104a7a654f310Anton Korobeynikov  return ResNode;
18637171571716b9cb7c5aeb5b45d95b1fbd0716d03Anton Korobeynikov}
187