1193323Sed//===-- MSP430ISelDAGToDAG.cpp - A dag to dag inst selector for MSP430 ----===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10193323Sed// This file defines an instruction selector for the MSP430 target. 11193323Sed// 12193323Sed//===----------------------------------------------------------------------===// 13193323Sed 14193323Sed#include "MSP430.h" 15193323Sed#include "MSP430TargetMachine.h" 16193323Sed#include "llvm/CodeGen/MachineFrameInfo.h" 17193323Sed#include "llvm/CodeGen/MachineFunction.h" 18193323Sed#include "llvm/CodeGen/MachineInstrBuilder.h" 19193323Sed#include "llvm/CodeGen/MachineRegisterInfo.h" 20193323Sed#include "llvm/CodeGen/SelectionDAG.h" 21193323Sed#include "llvm/CodeGen/SelectionDAGISel.h" 22249423Sdim#include "llvm/IR/CallingConv.h" 23249423Sdim#include "llvm/IR/Constants.h" 24249423Sdim#include "llvm/IR/DerivedTypes.h" 25249423Sdim#include "llvm/IR/Function.h" 26249423Sdim#include "llvm/IR/Intrinsics.h" 27193323Sed#include "llvm/Support/Compiler.h" 28193323Sed#include "llvm/Support/Debug.h" 29198090Srdivacky#include "llvm/Support/ErrorHandling.h" 30198090Srdivacky#include "llvm/Support/raw_ostream.h" 31249423Sdim#include "llvm/Target/TargetLowering.h" 32193323Sedusing namespace llvm; 33193323Sed 34199481Srdivackynamespace { 35199481Srdivacky struct MSP430ISelAddressMode { 36199481Srdivacky enum { 37199481Srdivacky RegBase, 38199481Srdivacky FrameIndexBase 39199481Srdivacky } BaseType; 40199481Srdivacky 41199481Srdivacky struct { // This is really a union, discriminated by BaseType! 42199481Srdivacky SDValue Reg; 43199481Srdivacky int FrameIndex; 44199481Srdivacky } Base; 45199481Srdivacky 46199481Srdivacky int16_t Disp; 47207618Srdivacky const GlobalValue *GV; 48207618Srdivacky const Constant *CP; 49207618Srdivacky const BlockAddress *BlockAddr; 50199481Srdivacky const char *ES; 51199481Srdivacky int JT; 52199481Srdivacky unsigned Align; // CP alignment. 53199481Srdivacky 54199481Srdivacky MSP430ISelAddressMode() 55199481Srdivacky : BaseType(RegBase), Disp(0), GV(0), CP(0), BlockAddr(0), 56199481Srdivacky ES(0), JT(-1), Align(0) { 57199481Srdivacky } 58199481Srdivacky 59199481Srdivacky bool hasSymbolicDisplacement() const { 60199481Srdivacky return GV != 0 || CP != 0 || ES != 0 || JT != -1; 61199481Srdivacky } 62199481Srdivacky 63199481Srdivacky void dump() { 64199481Srdivacky errs() << "MSP430ISelAddressMode " << this << '\n'; 65200581Srdivacky if (BaseType == RegBase && Base.Reg.getNode() != 0) { 66199481Srdivacky errs() << "Base.Reg "; 67199481Srdivacky Base.Reg.getNode()->dump(); 68200581Srdivacky } else if (BaseType == FrameIndexBase) { 69199481Srdivacky errs() << " Base.FrameIndex " << Base.FrameIndex << '\n'; 70199481Srdivacky } 71199481Srdivacky errs() << " Disp " << Disp << '\n'; 72199481Srdivacky if (GV) { 73199481Srdivacky errs() << "GV "; 74199481Srdivacky GV->dump(); 75199481Srdivacky } else if (CP) { 76199481Srdivacky errs() << " CP "; 77199481Srdivacky CP->dump(); 78199481Srdivacky errs() << " Align" << Align << '\n'; 79199481Srdivacky } else if (ES) { 80199481Srdivacky errs() << "ES "; 81199481Srdivacky errs() << ES << '\n'; 82199481Srdivacky } else if (JT != -1) 83199481Srdivacky errs() << " JT" << JT << " Align" << Align << '\n'; 84199481Srdivacky } 85199481Srdivacky }; 86199481Srdivacky} 87199481Srdivacky 88193323Sed/// MSP430DAGToDAGISel - MSP430 specific code to select MSP430 machine 89193323Sed/// instructions for SelectionDAG operations. 90193323Sed/// 91193323Sednamespace { 92193323Sed class MSP430DAGToDAGISel : public SelectionDAGISel { 93207618Srdivacky const MSP430TargetLowering &Lowering; 94193323Sed const MSP430Subtarget &Subtarget; 95193323Sed 96193323Sed public: 97193323Sed MSP430DAGToDAGISel(MSP430TargetMachine &TM, CodeGenOpt::Level OptLevel) 98193323Sed : SelectionDAGISel(TM, OptLevel), 99193323Sed Lowering(*TM.getTargetLowering()), 100193323Sed Subtarget(*TM.getSubtargetImpl()) { } 101193323Sed 102193323Sed virtual const char *getPassName() const { 103193323Sed return "MSP430 DAG->DAG Pattern Instruction Selection"; 104193323Sed } 105193323Sed 106199481Srdivacky bool MatchAddress(SDValue N, MSP430ISelAddressMode &AM); 107199481Srdivacky bool MatchWrapper(SDValue N, MSP430ISelAddressMode &AM); 108199481Srdivacky bool MatchAddressBase(SDValue N, MSP430ISelAddressMode &AM); 109199481Srdivacky 110198090Srdivacky virtual bool 111198090Srdivacky SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, 112198090Srdivacky std::vector<SDValue> &OutOps); 113198090Srdivacky 114193323Sed // Include the pieces autogenerated from the target description. 115193323Sed #include "MSP430GenDAGISel.inc" 116193323Sed 117193323Sed private: 118202375Srdivacky SDNode *Select(SDNode *N); 119202375Srdivacky SDNode *SelectIndexedLoad(SDNode *Op); 120202375Srdivacky SDNode *SelectIndexedBinOp(SDNode *Op, SDValue N1, SDValue N2, 121199481Srdivacky unsigned Opc8, unsigned Opc16); 122199481Srdivacky 123218893Sdim bool SelectAddr(SDValue Addr, SDValue &Base, SDValue &Disp); 124193323Sed }; 125193323Sed} // end anonymous namespace 126193323Sed 127193323Sed/// createMSP430ISelDag - This pass converts a legalized DAG into a 128193323Sed/// MSP430-specific DAG, ready for instruction scheduling. 129193323Sed/// 130193323SedFunctionPass *llvm::createMSP430ISelDag(MSP430TargetMachine &TM, 131193323Sed CodeGenOpt::Level OptLevel) { 132193323Sed return new MSP430DAGToDAGISel(TM, OptLevel); 133193323Sed} 134193323Sed 135199481Srdivacky 136199481Srdivacky/// MatchWrapper - Try to match MSP430ISD::Wrapper node into an addressing mode. 137199481Srdivacky/// These wrap things that will resolve down into a symbol reference. If no 138199481Srdivacky/// match is possible, this returns true, otherwise it returns false. 139199481Srdivackybool MSP430DAGToDAGISel::MatchWrapper(SDValue N, MSP430ISelAddressMode &AM) { 140199481Srdivacky // If the addressing mode already has a symbol as the displacement, we can 141199481Srdivacky // never match another symbol. 142199481Srdivacky if (AM.hasSymbolicDisplacement()) 143193323Sed return true; 144199481Srdivacky 145199481Srdivacky SDValue N0 = N.getOperand(0); 146199481Srdivacky 147199481Srdivacky if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(N0)) { 148199481Srdivacky AM.GV = G->getGlobal(); 149199481Srdivacky AM.Disp += G->getOffset(); 150199481Srdivacky //AM.SymbolFlags = G->getTargetFlags(); 151199481Srdivacky } else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(N0)) { 152199481Srdivacky AM.CP = CP->getConstVal(); 153199481Srdivacky AM.Align = CP->getAlignment(); 154199481Srdivacky AM.Disp += CP->getOffset(); 155199481Srdivacky //AM.SymbolFlags = CP->getTargetFlags(); 156199481Srdivacky } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(N0)) { 157199481Srdivacky AM.ES = S->getSymbol(); 158199481Srdivacky //AM.SymbolFlags = S->getTargetFlags(); 159199481Srdivacky } else if (JumpTableSDNode *J = dyn_cast<JumpTableSDNode>(N0)) { 160199481Srdivacky AM.JT = J->getIndex(); 161199481Srdivacky //AM.SymbolFlags = J->getTargetFlags(); 162199481Srdivacky } else { 163199481Srdivacky AM.BlockAddr = cast<BlockAddressSDNode>(N0)->getBlockAddress(); 164199481Srdivacky //AM.SymbolFlags = cast<BlockAddressSDNode>(N0)->getTargetFlags(); 165193323Sed } 166199481Srdivacky return false; 167199481Srdivacky} 168193323Sed 169199481Srdivacky/// MatchAddressBase - Helper for MatchAddress. Add the specified node to the 170199481Srdivacky/// specified addressing mode without any further recursion. 171199481Srdivackybool MSP430DAGToDAGISel::MatchAddressBase(SDValue N, MSP430ISelAddressMode &AM) { 172199481Srdivacky // Is the base register already occupied? 173199481Srdivacky if (AM.BaseType != MSP430ISelAddressMode::RegBase || AM.Base.Reg.getNode()) { 174199481Srdivacky // If so, we cannot select it. 175199481Srdivacky return true; 176199481Srdivacky } 177193323Sed 178199481Srdivacky // Default, generate it as a register. 179199481Srdivacky AM.BaseType = MSP430ISelAddressMode::RegBase; 180199481Srdivacky AM.Base.Reg = N; 181199481Srdivacky return false; 182199481Srdivacky} 183199481Srdivacky 184199481Srdivackybool MSP430DAGToDAGISel::MatchAddress(SDValue N, MSP430ISelAddressMode &AM) { 185204642Srdivacky DEBUG(errs() << "MatchAddress: "; AM.dump()); 186199481Srdivacky 187199481Srdivacky switch (N.getOpcode()) { 188199481Srdivacky default: break; 189199481Srdivacky case ISD::Constant: { 190199481Srdivacky uint64_t Val = cast<ConstantSDNode>(N)->getSExtValue(); 191199481Srdivacky AM.Disp += Val; 192199481Srdivacky return false; 193199481Srdivacky } 194199481Srdivacky 195199481Srdivacky case MSP430ISD::Wrapper: 196199481Srdivacky if (!MatchWrapper(N, AM)) 197199481Srdivacky return false; 198199481Srdivacky break; 199199481Srdivacky 200199481Srdivacky case ISD::FrameIndex: 201199481Srdivacky if (AM.BaseType == MSP430ISelAddressMode::RegBase 202199481Srdivacky && AM.Base.Reg.getNode() == 0) { 203199481Srdivacky AM.BaseType = MSP430ISelAddressMode::FrameIndexBase; 204199481Srdivacky AM.Base.FrameIndex = cast<FrameIndexSDNode>(N)->getIndex(); 205199481Srdivacky return false; 206193323Sed } 207193323Sed break; 208199481Srdivacky 209199481Srdivacky case ISD::ADD: { 210199481Srdivacky MSP430ISelAddressMode Backup = AM; 211199481Srdivacky if (!MatchAddress(N.getNode()->getOperand(0), AM) && 212199481Srdivacky !MatchAddress(N.getNode()->getOperand(1), AM)) 213199481Srdivacky return false; 214199481Srdivacky AM = Backup; 215199481Srdivacky if (!MatchAddress(N.getNode()->getOperand(1), AM) && 216199481Srdivacky !MatchAddress(N.getNode()->getOperand(0), AM)) 217199481Srdivacky return false; 218199481Srdivacky AM = Backup; 219199481Srdivacky 220199481Srdivacky break; 221199481Srdivacky } 222199481Srdivacky 223199481Srdivacky case ISD::OR: 224199481Srdivacky // Handle "X | C" as "X + C" iff X is known to have C bits clear. 225199481Srdivacky if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 226199481Srdivacky MSP430ISelAddressMode Backup = AM; 227199481Srdivacky uint64_t Offset = CN->getSExtValue(); 228199481Srdivacky // Start with the LHS as an addr mode. 229199481Srdivacky if (!MatchAddress(N.getOperand(0), AM) && 230199481Srdivacky // Address could not have picked a GV address for the displacement. 231199481Srdivacky AM.GV == NULL && 232199481Srdivacky // Check to see if the LHS & C is zero. 233199481Srdivacky CurDAG->MaskedValueIsZero(N.getOperand(0), CN->getAPIntValue())) { 234199481Srdivacky AM.Disp += Offset; 235199481Srdivacky return false; 236199481Srdivacky } 237199481Srdivacky AM = Backup; 238193323Sed } 239193323Sed break; 240199481Srdivacky } 241193323Sed 242199481Srdivacky return MatchAddressBase(N, AM); 243199481Srdivacky} 244193323Sed 245199481Srdivacky/// SelectAddr - returns true if it is able pattern match an addressing mode. 246199481Srdivacky/// It returns the operands which make up the maximal addressing mode it can 247199481Srdivacky/// match by reference. 248218893Sdimbool MSP430DAGToDAGISel::SelectAddr(SDValue N, 249199481Srdivacky SDValue &Base, SDValue &Disp) { 250199481Srdivacky MSP430ISelAddressMode AM; 251199481Srdivacky 252199481Srdivacky if (MatchAddress(N, AM)) 253199481Srdivacky return false; 254199481Srdivacky 255199481Srdivacky EVT VT = N.getValueType(); 256199481Srdivacky if (AM.BaseType == MSP430ISelAddressMode::RegBase) { 257199481Srdivacky if (!AM.Base.Reg.getNode()) 258199481Srdivacky AM.Base.Reg = CurDAG->getRegister(0, VT); 259199481Srdivacky } 260199481Srdivacky 261199481Srdivacky Base = (AM.BaseType == MSP430ISelAddressMode::FrameIndexBase) ? 262263508Sdim CurDAG->getTargetFrameIndex(AM.Base.FrameIndex, 263263508Sdim getTargetLowering()->getPointerTy()) : 264199481Srdivacky AM.Base.Reg; 265199481Srdivacky 266199481Srdivacky if (AM.GV) 267263508Sdim Disp = CurDAG->getTargetGlobalAddress(AM.GV, SDLoc(N), 268210299Sed MVT::i16, AM.Disp, 269199481Srdivacky 0/*AM.SymbolFlags*/); 270199481Srdivacky else if (AM.CP) 271199481Srdivacky Disp = CurDAG->getTargetConstantPool(AM.CP, MVT::i16, 272199481Srdivacky AM.Align, AM.Disp, 0/*AM.SymbolFlags*/); 273199481Srdivacky else if (AM.ES) 274199481Srdivacky Disp = CurDAG->getTargetExternalSymbol(AM.ES, MVT::i16, 0/*AM.SymbolFlags*/); 275199481Srdivacky else if (AM.JT != -1) 276199481Srdivacky Disp = CurDAG->getTargetJumpTable(AM.JT, MVT::i16, 0/*AM.SymbolFlags*/); 277199481Srdivacky else if (AM.BlockAddr) 278243830Sdim Disp = CurDAG->getTargetBlockAddress(AM.BlockAddr, MVT::i32, 0, 279243830Sdim 0/*AM.SymbolFlags*/); 280199481Srdivacky else 281199481Srdivacky Disp = CurDAG->getTargetConstant(AM.Disp, MVT::i16); 282199481Srdivacky 283193323Sed return true; 284193323Sed} 285193323Sed 286198090Srdivackybool MSP430DAGToDAGISel:: 287198090SrdivackySelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, 288198090Srdivacky std::vector<SDValue> &OutOps) { 289198090Srdivacky SDValue Op0, Op1; 290198090Srdivacky switch (ConstraintCode) { 291198090Srdivacky default: return true; 292198090Srdivacky case 'm': // memory 293218893Sdim if (!SelectAddr(Op, Op0, Op1)) 294198090Srdivacky return true; 295198090Srdivacky break; 296198090Srdivacky } 297193323Sed 298198090Srdivacky OutOps.push_back(Op0); 299198090Srdivacky OutOps.push_back(Op1); 300198090Srdivacky return false; 301198090Srdivacky} 302198090Srdivacky 303199481Srdivackystatic bool isValidIndexedLoad(const LoadSDNode *LD) { 304199481Srdivacky ISD::MemIndexedMode AM = LD->getAddressingMode(); 305199481Srdivacky if (AM != ISD::POST_INC || LD->getExtensionType() != ISD::NON_EXTLOAD) 306199481Srdivacky return false; 307199481Srdivacky 308199481Srdivacky EVT VT = LD->getMemoryVT(); 309199481Srdivacky 310199481Srdivacky switch (VT.getSimpleVT().SimpleTy) { 311199481Srdivacky case MVT::i8: 312199481Srdivacky // Sanity check 313199481Srdivacky if (cast<ConstantSDNode>(LD->getOffset())->getZExtValue() != 1) 314199481Srdivacky return false; 315199481Srdivacky 316199481Srdivacky break; 317199481Srdivacky case MVT::i16: 318199481Srdivacky // Sanity check 319199481Srdivacky if (cast<ConstantSDNode>(LD->getOffset())->getZExtValue() != 2) 320199481Srdivacky return false; 321199481Srdivacky 322199481Srdivacky break; 323199481Srdivacky default: 324199481Srdivacky return false; 325199481Srdivacky } 326199481Srdivacky 327199481Srdivacky return true; 328199481Srdivacky} 329199481Srdivacky 330202375SrdivackySDNode *MSP430DAGToDAGISel::SelectIndexedLoad(SDNode *N) { 331202375Srdivacky LoadSDNode *LD = cast<LoadSDNode>(N); 332199481Srdivacky if (!isValidIndexedLoad(LD)) 333199481Srdivacky return NULL; 334199481Srdivacky 335199481Srdivacky MVT VT = LD->getMemoryVT().getSimpleVT(); 336199481Srdivacky 337199481Srdivacky unsigned Opcode = 0; 338199481Srdivacky switch (VT.SimpleTy) { 339199481Srdivacky case MVT::i8: 340199481Srdivacky Opcode = MSP430::MOV8rm_POST; 341199481Srdivacky break; 342199481Srdivacky case MVT::i16: 343199481Srdivacky Opcode = MSP430::MOV16rm_POST; 344199481Srdivacky break; 345199481Srdivacky default: 346199481Srdivacky return NULL; 347199481Srdivacky } 348199481Srdivacky 349263508Sdim return CurDAG->getMachineNode(Opcode, SDLoc(N), 350199481Srdivacky VT, MVT::i16, MVT::Other, 351199481Srdivacky LD->getBasePtr(), LD->getChain()); 352199481Srdivacky} 353199481Srdivacky 354202375SrdivackySDNode *MSP430DAGToDAGISel::SelectIndexedBinOp(SDNode *Op, 355199481Srdivacky SDValue N1, SDValue N2, 356199481Srdivacky unsigned Opc8, unsigned Opc16) { 357199481Srdivacky if (N1.getOpcode() == ISD::LOAD && 358199481Srdivacky N1.hasOneUse() && 359207618Srdivacky IsLegalToFold(N1, Op, Op, OptLevel)) { 360199481Srdivacky LoadSDNode *LD = cast<LoadSDNode>(N1); 361199481Srdivacky if (!isValidIndexedLoad(LD)) 362199481Srdivacky return NULL; 363199481Srdivacky 364199481Srdivacky MVT VT = LD->getMemoryVT().getSimpleVT(); 365199481Srdivacky unsigned Opc = (VT == MVT::i16 ? Opc16 : Opc8); 366199481Srdivacky MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1); 367199481Srdivacky MemRefs0[0] = cast<MemSDNode>(N1)->getMemOperand(); 368199481Srdivacky SDValue Ops0[] = { N2, LD->getBasePtr(), LD->getChain() }; 369199481Srdivacky SDNode *ResNode = 370202375Srdivacky CurDAG->SelectNodeTo(Op, Opc, 371199481Srdivacky VT, MVT::i16, MVT::Other, 372199481Srdivacky Ops0, 3); 373199481Srdivacky cast<MachineSDNode>(ResNode)->setMemRefs(MemRefs0, MemRefs0 + 1); 374199481Srdivacky // Transfer chain. 375199481Srdivacky ReplaceUses(SDValue(N1.getNode(), 2), SDValue(ResNode, 2)); 376199481Srdivacky // Transfer writeback. 377199481Srdivacky ReplaceUses(SDValue(N1.getNode(), 1), SDValue(ResNode, 1)); 378199481Srdivacky return ResNode; 379199481Srdivacky } 380199481Srdivacky 381199481Srdivacky return NULL; 382199481Srdivacky} 383199481Srdivacky 384199481Srdivacky 385202375SrdivackySDNode *MSP430DAGToDAGISel::Select(SDNode *Node) { 386263508Sdim SDLoc dl(Node); 387193323Sed 388193323Sed // Dump information about the Node being selected 389204642Srdivacky DEBUG(errs() << "Selecting: "); 390193323Sed DEBUG(Node->dump(CurDAG)); 391198090Srdivacky DEBUG(errs() << "\n"); 392193323Sed 393193323Sed // If we have a custom node, we already have selected! 394193323Sed if (Node->isMachineOpcode()) { 395204642Srdivacky DEBUG(errs() << "== "; 396198090Srdivacky Node->dump(CurDAG); 397198090Srdivacky errs() << "\n"); 398255804Sdim Node->setNodeId(-1); 399193323Sed return NULL; 400193323Sed } 401193323Sed 402193323Sed // Few custom selection stuff. 403193323Sed switch (Node->getOpcode()) { 404193323Sed default: break; 405193323Sed case ISD::FrameIndex: { 406202375Srdivacky assert(Node->getValueType(0) == MVT::i16); 407193323Sed int FI = cast<FrameIndexSDNode>(Node)->getIndex(); 408193323Sed SDValue TFI = CurDAG->getTargetFrameIndex(FI, MVT::i16); 409193323Sed if (Node->hasOneUse()) 410193323Sed return CurDAG->SelectNodeTo(Node, MSP430::ADD16ri, MVT::i16, 411193323Sed TFI, CurDAG->getTargetConstant(0, MVT::i16)); 412198090Srdivacky return CurDAG->getMachineNode(MSP430::ADD16ri, dl, MVT::i16, 413198090Srdivacky TFI, CurDAG->getTargetConstant(0, MVT::i16)); 414193323Sed } 415199481Srdivacky case ISD::LOAD: 416202375Srdivacky if (SDNode *ResNode = SelectIndexedLoad(Node)) 417199481Srdivacky return ResNode; 418199481Srdivacky // Other cases are autogenerated. 419199481Srdivacky break; 420199481Srdivacky case ISD::ADD: 421199481Srdivacky if (SDNode *ResNode = 422202375Srdivacky SelectIndexedBinOp(Node, 423202375Srdivacky Node->getOperand(0), Node->getOperand(1), 424199481Srdivacky MSP430::ADD8rm_POST, MSP430::ADD16rm_POST)) 425199481Srdivacky return ResNode; 426199481Srdivacky else if (SDNode *ResNode = 427202375Srdivacky SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0), 428199481Srdivacky MSP430::ADD8rm_POST, MSP430::ADD16rm_POST)) 429199481Srdivacky return ResNode; 430199481Srdivacky 431199481Srdivacky // Other cases are autogenerated. 432199481Srdivacky break; 433199481Srdivacky case ISD::SUB: 434199481Srdivacky if (SDNode *ResNode = 435202375Srdivacky SelectIndexedBinOp(Node, 436202375Srdivacky Node->getOperand(0), Node->getOperand(1), 437199481Srdivacky MSP430::SUB8rm_POST, MSP430::SUB16rm_POST)) 438199481Srdivacky return ResNode; 439199481Srdivacky 440199481Srdivacky // Other cases are autogenerated. 441199481Srdivacky break; 442199481Srdivacky case ISD::AND: 443199481Srdivacky if (SDNode *ResNode = 444202375Srdivacky SelectIndexedBinOp(Node, 445202375Srdivacky Node->getOperand(0), Node->getOperand(1), 446199481Srdivacky MSP430::AND8rm_POST, MSP430::AND16rm_POST)) 447199481Srdivacky return ResNode; 448199481Srdivacky else if (SDNode *ResNode = 449202375Srdivacky SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0), 450199481Srdivacky MSP430::AND8rm_POST, MSP430::AND16rm_POST)) 451199481Srdivacky return ResNode; 452199481Srdivacky 453199481Srdivacky // Other cases are autogenerated. 454199481Srdivacky break; 455199481Srdivacky case ISD::OR: 456199481Srdivacky if (SDNode *ResNode = 457202375Srdivacky SelectIndexedBinOp(Node, 458202375Srdivacky Node->getOperand(0), Node->getOperand(1), 459199481Srdivacky MSP430::OR8rm_POST, MSP430::OR16rm_POST)) 460199481Srdivacky return ResNode; 461199481Srdivacky else if (SDNode *ResNode = 462202375Srdivacky SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0), 463199481Srdivacky MSP430::OR8rm_POST, MSP430::OR16rm_POST)) 464199481Srdivacky return ResNode; 465199481Srdivacky 466199481Srdivacky // Other cases are autogenerated. 467199481Srdivacky break; 468199481Srdivacky case ISD::XOR: 469199481Srdivacky if (SDNode *ResNode = 470202375Srdivacky SelectIndexedBinOp(Node, 471202375Srdivacky Node->getOperand(0), Node->getOperand(1), 472199481Srdivacky MSP430::XOR8rm_POST, MSP430::XOR16rm_POST)) 473199481Srdivacky return ResNode; 474199481Srdivacky else if (SDNode *ResNode = 475202375Srdivacky SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0), 476199481Srdivacky MSP430::XOR8rm_POST, MSP430::XOR16rm_POST)) 477199481Srdivacky return ResNode; 478199481Srdivacky 479199481Srdivacky // Other cases are autogenerated. 480199481Srdivacky break; 481193323Sed } 482193323Sed 483193323Sed // Select the default instruction 484202375Srdivacky SDNode *ResNode = SelectCode(Node); 485193323Sed 486204642Srdivacky DEBUG(errs() << "=> "); 487202375Srdivacky if (ResNode == NULL || ResNode == Node) 488202375Srdivacky DEBUG(Node->dump(CurDAG)); 489193323Sed else 490193323Sed DEBUG(ResNode->dump(CurDAG)); 491198090Srdivacky DEBUG(errs() << "\n"); 492193323Sed 493193323Sed return ResNode; 494193323Sed} 495