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