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