MSP430ISelDAGToDAG.cpp revision 263508
1119452Sobrien//===-- MSP430ISelDAGToDAG.cpp - A dag to dag inst selector for MSP430 ----===// 2101225Sphk// 3101225Sphk// The LLVM Compiler Infrastructure 4101225Sphk// 5101225Sphk// This file is distributed under the University of Illinois Open Source 6101225Sphk// License. See LICENSE.TXT for details. 7101225Sphk// 8101225Sphk//===----------------------------------------------------------------------===// 9101225Sphk// 10102934Sphk// This file defines an instruction selector for the MSP430 target. 11102934Sphk// 12102934Sphk//===----------------------------------------------------------------------===// 13102934Sphk 14102934Sphk#include "MSP430.h" 15102934Sphk#include "MSP430TargetMachine.h" 16102934Sphk#include "llvm/CodeGen/MachineFrameInfo.h" 17102934Sphk#include "llvm/CodeGen/MachineFunction.h" 18102934Sphk#include "llvm/CodeGen/MachineInstrBuilder.h" 19109327Sphk#include "llvm/CodeGen/MachineRegisterInfo.h" 20123015Sphk#include "llvm/CodeGen/SelectionDAG.h" 21123015Sphk#include "llvm/CodeGen/SelectionDAGISel.h" 22123015Sphk#include "llvm/IR/CallingConv.h" 23123015Sphk#include "llvm/IR/Constants.h" 24123015Sphk#include "llvm/IR/DerivedTypes.h" 25123015Sphk#include "llvm/IR/Function.h" 26123015Sphk#include "llvm/IR/Intrinsics.h" 27123015Sphk#include "llvm/Support/Compiler.h" 28123015Sphk#include "llvm/Support/Debug.h" 29123015Sphk#include "llvm/Support/ErrorHandling.h" 30123015Sphk#include "llvm/Support/raw_ostream.h" 31123015Sphk#include "llvm/Target/TargetLowering.h" 32123015Sphkusing namespace llvm; 33123015Sphk 34123015Sphknamespace { 35123015Sphk struct MSP430ISelAddressMode { 36123015Sphk enum { 37123015Sphk RegBase, 38123015Sphk FrameIndexBase 39101225Sphk } BaseType; 40102934Sphk 41115683Sobrien struct { // This is really a union, discriminated by BaseType! 42115683Sobrien SDValue Reg; 43115683Sobrien int FrameIndex; 44111138Sphk } Base; 45101225Sphk 46101225Sphk int16_t Disp; 47101225Sphk const GlobalValue *GV; 48101225Sphk const Constant *CP; 49102934Sphk const BlockAddress *BlockAddr; 50123015Sphk const char *ES; 51102934Sphk int JT; 52102934Sphk unsigned Align; // CP alignment. 53103482Sphk 54103482Sphk MSP430ISelAddressMode() 55103482Sphk : BaseType(RegBase), Disp(0), GV(0), CP(0), BlockAddr(0), 56103482Sphk ES(0), JT(-1), Align(0) { 57109327Sphk } 58109327Sphk 59111647Sphk bool hasSymbolicDisplacement() const { 60101225Sphk return GV != 0 || CP != 0 || ES != 0 || JT != -1; 61121944Sphk } 62101225Sphk 63124144Sphk void dump() { 64101225Sphk errs() << "MSP430ISelAddressMode " << this << '\n'; 65102934Sphk if (BaseType == RegBase && Base.Reg.getNode() != 0) { 66102934Sphk errs() << "Base.Reg "; 67102934Sphk Base.Reg.getNode()->dump(); 68123015Sphk } else if (BaseType == FrameIndexBase) { 69123015Sphk errs() << " Base.FrameIndex " << Base.FrameIndex << '\n'; 70124144Sphk } 71127039Sphk errs() << " Disp " << Disp << '\n'; 72102934Sphk if (GV) { 73123015Sphk errs() << "GV "; 74109327Sphk GV->dump(); 75127039Sphk } else if (CP) { 76127039Sphk errs() << " CP "; 77127039Sphk CP->dump(); 78123015Sphk errs() << " Align" << Align << '\n'; 79127039Sphk } else if (ES) { 80127039Sphk errs() << "ES "; 81130585Sphk errs() << ES << '\n'; 82109327Sphk } else if (JT != -1) 83109327Sphk errs() << " JT" << JT << " Align" << Align << '\n'; 84123015Sphk } 85123015Sphk }; 86123015Sphk} 87123015Sphk 88123015Sphk/// MSP430DAGToDAGISel - MSP430 specific code to select MSP430 machine 89123015Sphk/// instructions for SelectionDAG operations. 90123015Sphk/// 91123015Sphknamespace { 92123015Sphk class MSP430DAGToDAGISel : public SelectionDAGISel { 93124144Sphk const MSP430TargetLowering &Lowering; 94123015Sphk const MSP430Subtarget &Subtarget; 95123015Sphk 96123015Sphk public: 97123015Sphk MSP430DAGToDAGISel(MSP430TargetMachine &TM, CodeGenOpt::Level OptLevel) 98123015Sphk : SelectionDAGISel(TM, OptLevel), 99123015Sphk Lowering(*TM.getTargetLowering()), 100123015Sphk Subtarget(*TM.getSubtargetImpl()) { } 101123015Sphk 102126762Sjb virtual const char *getPassName() const { 103126762Sjb return "MSP430 DAG->DAG Pattern Instruction Selection"; 104126762Sjb } 105126762Sjb 106123015Sphk bool MatchAddress(SDValue N, MSP430ISelAddressMode &AM); 107123015Sphk bool MatchWrapper(SDValue N, MSP430ISelAddressMode &AM); 108123015Sphk bool MatchAddressBase(SDValue N, MSP430ISelAddressMode &AM); 109123015Sphk 110123015Sphk virtual bool 111123015Sphk SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, 112123015Sphk std::vector<SDValue> &OutOps); 113123015Sphk 114123015Sphk // Include the pieces autogenerated from the target description. 115123015Sphk #include "MSP430GenDAGISel.inc" 116123015Sphk 117123015Sphk private: 118127801Sphk SDNode *Select(SDNode *N); 119127801Sphk SDNode *SelectIndexedLoad(SDNode *Op); 120127801Sphk SDNode *SelectIndexedBinOp(SDNode *Op, SDValue N1, SDValue N2, 121123015Sphk unsigned Opc8, unsigned Opc16); 122123015Sphk 123123015Sphk bool SelectAddr(SDValue Addr, SDValue &Base, SDValue &Disp); 124123015Sphk }; 125123015Sphk} // end anonymous namespace 126123015Sphk 127123015Sphk/// createMSP430ISelDag - This pass converts a legalized DAG into a 128123015Sphk/// MSP430-specific DAG, ready for instruction scheduling. 129123015Sphk/// 130123015SphkFunctionPass *llvm::createMSP430ISelDag(MSP430TargetMachine &TM, 131123015Sphk CodeGenOpt::Level OptLevel) { 132123015Sphk return new MSP430DAGToDAGISel(TM, OptLevel); 133123015Sphk} 134123015Sphk 135123015Sphk 136123015Sphk/// MatchWrapper - Try to match MSP430ISD::Wrapper node into an addressing mode. 137123015Sphk/// These wrap things that will resolve down into a symbol reference. If no 138123015Sphk/// match is possible, this returns true, otherwise it returns false. 139123015Sphkbool MSP430DAGToDAGISel::MatchWrapper(SDValue N, MSP430ISelAddressMode &AM) { 140123015Sphk // If the addressing mode already has a symbol as the displacement, we can 141123015Sphk // never match another symbol. 142123015Sphk if (AM.hasSymbolicDisplacement()) 143123015Sphk return true; 144123015Sphk 145123015Sphk SDValue N0 = N.getOperand(0); 146123015Sphk 147123015Sphk if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(N0)) { 148123015Sphk AM.GV = G->getGlobal(); 149123015Sphk AM.Disp += G->getOffset(); 150123015Sphk //AM.SymbolFlags = G->getTargetFlags(); 151126762Sjb } else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(N0)) { 152127801Sphk AM.CP = CP->getConstVal(); 153127801Sphk AM.Align = CP->getAlignment(); 154127801Sphk AM.Disp += CP->getOffset(); 155127801Sphk //AM.SymbolFlags = CP->getTargetFlags(); 156123015Sphk } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(N0)) { 157123015Sphk AM.ES = S->getSymbol(); 158123015Sphk //AM.SymbolFlags = S->getTargetFlags(); 159124144Sphk } else if (JumpTableSDNode *J = dyn_cast<JumpTableSDNode>(N0)) { 160123015Sphk AM.JT = J->getIndex(); 161123015Sphk //AM.SymbolFlags = J->getTargetFlags(); 162123015Sphk } else { 163123015Sphk AM.BlockAddr = cast<BlockAddressSDNode>(N0)->getBlockAddress(); 164123015Sphk //AM.SymbolFlags = cast<BlockAddressSDNode>(N0)->getTargetFlags(); 165123015Sphk } 166127039Sphk return false; 167127039Sphk} 168127039Sphk 169124144Sphk/// MatchAddressBase - Helper for MatchAddress. Add the specified node to the 170123015Sphk/// specified addressing mode without any further recursion. 171123015Sphkbool MSP430DAGToDAGISel::MatchAddressBase(SDValue N, MSP430ISelAddressMode &AM) { 172123015Sphk // Is the base register already occupied? 173123015Sphk if (AM.BaseType != MSP430ISelAddressMode::RegBase || AM.Base.Reg.getNode()) { 174123015Sphk // If so, we cannot select it. 175123015Sphk return true; 176123015Sphk } 177123015Sphk 178123015Sphk // Default, generate it as a register. 179124144Sphk AM.BaseType = MSP430ISelAddressMode::RegBase; 180123015Sphk AM.Base.Reg = N; 181123015Sphk return false; 182123015Sphk} 183123015Sphk 184123015Sphkbool MSP430DAGToDAGISel::MatchAddress(SDValue N, MSP430ISelAddressMode &AM) { 185123015Sphk DEBUG(errs() << "MatchAddress: "; AM.dump()); 186123015Sphk 187123015Sphk switch (N.getOpcode()) { 188123015Sphk default: break; 189123015Sphk case ISD::Constant: { 190123015Sphk uint64_t Val = cast<ConstantSDNode>(N)->getSExtValue(); 191123015Sphk AM.Disp += Val; 192128677Sphk return false; 193128677Sphk } 194123015Sphk 195123015Sphk case MSP430ISD::Wrapper: 196123015Sphk if (!MatchWrapper(N, AM)) 197123015Sphk return false; 198123015Sphk break; 199123015Sphk 200123015Sphk case ISD::FrameIndex: 201123015Sphk if (AM.BaseType == MSP430ISelAddressMode::RegBase 202123015Sphk && AM.Base.Reg.getNode() == 0) { 203123015Sphk AM.BaseType = MSP430ISelAddressMode::FrameIndexBase; 204123015Sphk AM.Base.FrameIndex = cast<FrameIndexSDNode>(N)->getIndex(); 205123015Sphk return false; 206123015Sphk } 207123015Sphk break; 208123015Sphk 209123015Sphk case ISD::ADD: { 210123015Sphk MSP430ISelAddressMode Backup = AM; 211123015Sphk if (!MatchAddress(N.getNode()->getOperand(0), AM) && 212123015Sphk !MatchAddress(N.getNode()->getOperand(1), AM)) 213109327Sphk return false; 214109327Sphk AM = Backup; 215109327Sphk if (!MatchAddress(N.getNode()->getOperand(1), AM) && 216109327Sphk !MatchAddress(N.getNode()->getOperand(0), AM)) 217127039Sphk return false; 218127039Sphk AM = Backup; 219109327Sphk 220123015Sphk break; 221127039Sphk } 222127039Sphk 223127039Sphk case ISD::OR: 224127039Sphk // Handle "X | C" as "X + C" iff X is known to have C bits clear. 225127039Sphk if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 226127039Sphk MSP430ISelAddressMode Backup = AM; 227127039Sphk uint64_t Offset = CN->getSExtValue(); 228127039Sphk // Start with the LHS as an addr mode. 229127039Sphk if (!MatchAddress(N.getOperand(0), AM) && 230127039Sphk // Address could not have picked a GV address for the displacement. 231127039Sphk AM.GV == NULL && 232127039Sphk // Check to see if the LHS & C is zero. 233123015Sphk CurDAG->MaskedValueIsZero(N.getOperand(0), CN->getAPIntValue())) { 234123015Sphk AM.Disp += Offset; 235123015Sphk return false; 236123015Sphk } 237123015Sphk AM = Backup; 238123015Sphk } 239123015Sphk break; 240127039Sphk } 241123015Sphk 242123015Sphk return MatchAddressBase(N, AM); 243123015Sphk} 244109327Sphk 245123015Sphk/// SelectAddr - returns true if it is able pattern match an addressing mode. 246109327Sphk/// It returns the operands which make up the maximal addressing mode it can 247123015Sphk/// match by reference. 248123015Sphkbool MSP430DAGToDAGISel::SelectAddr(SDValue N, 249123015Sphk SDValue &Base, SDValue &Disp) { 250123015Sphk MSP430ISelAddressMode AM; 251124144Sphk 252109327Sphk if (MatchAddress(N, AM)) 253123015Sphk return false; 254123015Sphk 255127039Sphk EVT VT = N.getValueType(); 256127039Sphk if (AM.BaseType == MSP430ISelAddressMode::RegBase) { 257127039Sphk if (!AM.Base.Reg.getNode()) 258127039Sphk AM.Base.Reg = CurDAG->getRegister(0, VT); 259127039Sphk } 260127039Sphk 261109327Sphk Base = (AM.BaseType == MSP430ISelAddressMode::FrameIndexBase) ? 262127039Sphk CurDAG->getTargetFrameIndex(AM.Base.FrameIndex, 263109327Sphk getTargetLowering()->getPointerTy()) : 264123015Sphk AM.Base.Reg; 265123015Sphk 266123015Sphk if (AM.GV) 267124144Sphk Disp = CurDAG->getTargetGlobalAddress(AM.GV, SDLoc(N), 268109327Sphk MVT::i16, AM.Disp, 269123015Sphk 0/*AM.SymbolFlags*/); 270109327Sphk else if (AM.CP) 271102935Sphk Disp = CurDAG->getTargetConstantPool(AM.CP, MVT::i16, 272102935Sphk AM.Align, AM.Disp, 0/*AM.SymbolFlags*/); 273102935Sphk else if (AM.ES) 274123015Sphk Disp = CurDAG->getTargetExternalSymbol(AM.ES, MVT::i16, 0/*AM.SymbolFlags*/); 275123015Sphk else if (AM.JT != -1) 276124144Sphk Disp = CurDAG->getTargetJumpTable(AM.JT, MVT::i16, 0/*AM.SymbolFlags*/); 277102935Sphk else if (AM.BlockAddr) 278102935Sphk Disp = CurDAG->getTargetBlockAddress(AM.BlockAddr, MVT::i32, 0, 279109327Sphk 0/*AM.SymbolFlags*/); 280109327Sphk else 281109327Sphk Disp = CurDAG->getTargetConstant(AM.Disp, MVT::i16); 282109327Sphk 283123015Sphk return true; 284123015Sphk} 285109327Sphk 286109327Sphkbool MSP430DAGToDAGISel:: 287102935SphkSelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, 288102935Sphk std::vector<SDValue> &OutOps) { 289109327Sphk SDValue Op0, Op1; 290102935Sphk switch (ConstraintCode) { 291123015Sphk default: return true; 292119715Sphk case 'm': // memory 293119715Sphk if (!SelectAddr(Op, Op0, Op1)) 294102935Sphk return true; 295102935Sphk break; 296109327Sphk } 297109327Sphk 298109327Sphk OutOps.push_back(Op0); 299109327Sphk OutOps.push_back(Op1); 300109327Sphk return false; 301109327Sphk} 302109327Sphk 303109327Sphkstatic bool isValidIndexedLoad(const LoadSDNode *LD) { 304109327Sphk ISD::MemIndexedMode AM = LD->getAddressingMode(); 305109327Sphk if (AM != ISD::POST_INC || LD->getExtensionType() != ISD::NON_EXTLOAD) 306109327Sphk return false; 307109327Sphk 308109327Sphk EVT VT = LD->getMemoryVT(); 309109327Sphk 310109327Sphk switch (VT.getSimpleVT().SimpleTy) { 311109327Sphk case MVT::i8: 312123015Sphk // Sanity check 313123015Sphk if (cast<ConstantSDNode>(LD->getOffset())->getZExtValue() != 1) 314123015Sphk return false; 315123015Sphk 316102934Sphk break; 317102934Sphk case MVT::i16: 318102934Sphk // Sanity check 319102934Sphk if (cast<ConstantSDNode>(LD->getOffset())->getZExtValue() != 2) 320102934Sphk return false; 321102934Sphk 322124144Sphk break; 323124144Sphk default: 324102934Sphk return false; 325102934Sphk } 326102934Sphk 327102934Sphk return true; 328102934Sphk} 329123015Sphk 330102934SphkSDNode *MSP430DAGToDAGISel::SelectIndexedLoad(SDNode *N) { 331102934Sphk LoadSDNode *LD = cast<LoadSDNode>(N); 332102934Sphk if (!isValidIndexedLoad(LD)) 333102934Sphk return NULL; 334123015Sphk 335123015Sphk MVT VT = LD->getMemoryVT().getSimpleVT(); 336103168Ssam 337102935Sphk unsigned Opcode = 0; 338102935Sphk switch (VT.SimpleTy) { 339124144Sphk case MVT::i8: 340124144Sphk Opcode = MSP430::MOV8rm_POST; 341109327Sphk break; 342123015Sphk case MVT::i16: 343109327Sphk Opcode = MSP430::MOV16rm_POST; 344124144Sphk break; 345124144Sphk default: 346124144Sphk return NULL; 347124144Sphk } 348109327Sphk 349109327Sphk return CurDAG->getMachineNode(Opcode, SDLoc(N), 350109327Sphk VT, MVT::i16, MVT::Other, 351102935Sphk LD->getBasePtr(), LD->getChain()); 352102934Sphk} 353102934Sphk 354103482SphkSDNode *MSP430DAGToDAGISel::SelectIndexedBinOp(SDNode *Op, 355126370Sphk SDValue N1, SDValue N2, 356101225Sphk unsigned Opc8, unsigned Opc16) { 357111647Sphk if (N1.getOpcode() == ISD::LOAD && 358111647Sphk N1.hasOneUse() && 359111647Sphk IsLegalToFold(N1, Op, Op, OptLevel)) { 360126370Sphk LoadSDNode *LD = cast<LoadSDNode>(N1); 361126370Sphk if (!isValidIndexedLoad(LD)) 362111647Sphk return NULL; 363111647Sphk 364111647Sphk MVT VT = LD->getMemoryVT().getSimpleVT(); 365111647Sphk unsigned Opc = (VT == MVT::i16 ? Opc16 : Opc8); 366111647Sphk MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1); 367111647Sphk MemRefs0[0] = cast<MemSDNode>(N1)->getMemOperand(); 368111647Sphk SDValue Ops0[] = { N2, LD->getBasePtr(), LD->getChain() }; 369111647Sphk SDNode *ResNode = 370111647Sphk CurDAG->SelectNodeTo(Op, Opc, 371111647Sphk VT, MVT::i16, MVT::Other, 372111647Sphk Ops0, 3); 373124144Sphk cast<MachineSDNode>(ResNode)->setMemRefs(MemRefs0, MemRefs0 + 1); 374124144Sphk // Transfer chain. 375111647Sphk ReplaceUses(SDValue(N1.getNode(), 2), SDValue(ResNode, 2)); 376111647Sphk // Transfer writeback. 377124144Sphk ReplaceUses(SDValue(N1.getNode(), 1), SDValue(ResNode, 1)); 378124144Sphk return ResNode; 379124144Sphk } 380111647Sphk 381111647Sphk return NULL; 382124144Sphk} 383124144Sphk 384124144Sphk 385111647SphkSDNode *MSP430DAGToDAGISel::Select(SDNode *Node) { 386111647Sphk SDLoc dl(Node); 387111647Sphk 388124144Sphk // Dump information about the Node being selected 389124144Sphk DEBUG(errs() << "Selecting: "); 390111647Sphk DEBUG(Node->dump(CurDAG)); 391124144Sphk DEBUG(errs() << "\n"); 392126370Sphk 393126370Sphk // If we have a custom node, we already have selected! 394126370Sphk if (Node->isMachineOpcode()) { 395124144Sphk DEBUG(errs() << "== "; 396124144Sphk Node->dump(CurDAG); 397124144Sphk errs() << "\n"); 398124144Sphk Node->setNodeId(-1); 399124144Sphk return NULL; 400124144Sphk } 401124144Sphk 402111647Sphk // Few custom selection stuff. 403126370Sphk switch (Node->getOpcode()) { 404111647Sphk default: break; 405111647Sphk case ISD::FrameIndex: { 406111647Sphk assert(Node->getValueType(0) == MVT::i16); 407111647Sphk int FI = cast<FrameIndexSDNode>(Node)->getIndex(); 408130585Sphk SDValue TFI = CurDAG->getTargetFrameIndex(FI, MVT::i16); 409126370Sphk if (Node->hasOneUse()) 410126370Sphk return CurDAG->SelectNodeTo(Node, MSP430::ADD16ri, MVT::i16, 411126370Sphk TFI, CurDAG->getTargetConstant(0, MVT::i16)); 412126370Sphk return CurDAG->getMachineNode(MSP430::ADD16ri, dl, MVT::i16, 413126370Sphk TFI, CurDAG->getTargetConstant(0, MVT::i16)); 414126370Sphk } 415126370Sphk case ISD::LOAD: 416126370Sphk if (SDNode *ResNode = SelectIndexedLoad(Node)) 417130585Sphk return ResNode; 418101225Sphk // Other cases are autogenerated. 419109327Sphk break; 420109327Sphk case ISD::ADD: 421126370Sphk if (SDNode *ResNode = 422123015Sphk SelectIndexedBinOp(Node, 423123015Sphk Node->getOperand(0), Node->getOperand(1), 424123015Sphk MSP430::ADD8rm_POST, MSP430::ADD16rm_POST)) 425123015Sphk return ResNode; 426109327Sphk else if (SDNode *ResNode = 427109327Sphk SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0), 428109327Sphk MSP430::ADD8rm_POST, MSP430::ADD16rm_POST)) 429109327Sphk return ResNode; 430123015Sphk 431109327Sphk // Other cases are autogenerated. 432123015Sphk break; 433109327Sphk case ISD::SUB: 434123015Sphk if (SDNode *ResNode = 435126370Sphk SelectIndexedBinOp(Node, 436109327Sphk Node->getOperand(0), Node->getOperand(1), 437123015Sphk MSP430::SUB8rm_POST, MSP430::SUB16rm_POST)) 438109327Sphk return ResNode; 439109327Sphk 440101225Sphk // Other cases are autogenerated. 441101225Sphk break; 442126370Sphk case ISD::AND: 443126370Sphk if (SDNode *ResNode = 444126370Sphk SelectIndexedBinOp(Node, 445126370Sphk Node->getOperand(0), Node->getOperand(1), 446126370Sphk MSP430::AND8rm_POST, MSP430::AND16rm_POST)) 447126370Sphk return ResNode; 448126370Sphk else if (SDNode *ResNode = 449126370Sphk SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0), 450126370Sphk MSP430::AND8rm_POST, MSP430::AND16rm_POST)) 451126370Sphk return ResNode; 452126370Sphk 453126370Sphk // Other cases are autogenerated. 454126370Sphk break; 455126370Sphk case ISD::OR: 456126370Sphk if (SDNode *ResNode = 457126370Sphk SelectIndexedBinOp(Node, 458126370Sphk Node->getOperand(0), Node->getOperand(1), 459126370Sphk MSP430::OR8rm_POST, MSP430::OR16rm_POST)) 460126370Sphk return ResNode; 461126370Sphk else if (SDNode *ResNode = 462126370Sphk SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0), 463126370Sphk MSP430::OR8rm_POST, MSP430::OR16rm_POST)) 464126370Sphk return ResNode; 465126370Sphk 466126370Sphk // Other cases are autogenerated. 467126370Sphk break; 468126370Sphk case ISD::XOR: 469126370Sphk if (SDNode *ResNode = 470126370Sphk SelectIndexedBinOp(Node, 471126370Sphk Node->getOperand(0), Node->getOperand(1), 472126370Sphk MSP430::XOR8rm_POST, MSP430::XOR16rm_POST)) 473126370Sphk return ResNode; 474126370Sphk else if (SDNode *ResNode = 475126370Sphk SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0), 476126370Sphk MSP430::XOR8rm_POST, MSP430::XOR16rm_POST)) 477126370Sphk return ResNode; 478126370Sphk 479126370Sphk // Other cases are autogenerated. 480126370Sphk break; 481126370Sphk } 482126370Sphk 483126370Sphk // Select the default instruction 484126370Sphk SDNode *ResNode = SelectCode(Node); 485126370Sphk 486126370Sphk DEBUG(errs() << "=> "); 487 if (ResNode == NULL || ResNode == Node) 488 DEBUG(Node->dump(CurDAG)); 489 else 490 DEBUG(ResNode->dump(CurDAG)); 491 DEBUG(errs() << "\n"); 492 493 return ResNode; 494} 495