MSP430ISelDAGToDAG.cpp revision 309124
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/Debug.h" 28198090Srdivacky#include "llvm/Support/ErrorHandling.h" 29198090Srdivacky#include "llvm/Support/raw_ostream.h" 30249423Sdim#include "llvm/Target/TargetLowering.h" 31193323Sedusing namespace llvm; 32193323Sed 33276479Sdim#define DEBUG_TYPE "msp430-isel" 34276479Sdim 35199481Srdivackynamespace { 36199481Srdivacky struct MSP430ISelAddressMode { 37199481Srdivacky enum { 38199481Srdivacky RegBase, 39199481Srdivacky FrameIndexBase 40199481Srdivacky } BaseType; 41199481Srdivacky 42199481Srdivacky struct { // This is really a union, discriminated by BaseType! 43199481Srdivacky SDValue Reg; 44199481Srdivacky int FrameIndex; 45199481Srdivacky } Base; 46199481Srdivacky 47199481Srdivacky int16_t Disp; 48207618Srdivacky const GlobalValue *GV; 49207618Srdivacky const Constant *CP; 50207618Srdivacky const BlockAddress *BlockAddr; 51199481Srdivacky const char *ES; 52199481Srdivacky int JT; 53199481Srdivacky unsigned Align; // CP alignment. 54199481Srdivacky 55199481Srdivacky MSP430ISelAddressMode() 56276479Sdim : BaseType(RegBase), Disp(0), GV(nullptr), CP(nullptr), 57276479Sdim BlockAddr(nullptr), ES(nullptr), JT(-1), Align(0) { 58199481Srdivacky } 59199481Srdivacky 60199481Srdivacky bool hasSymbolicDisplacement() const { 61276479Sdim return GV != nullptr || CP != nullptr || ES != nullptr || JT != -1; 62199481Srdivacky } 63199481Srdivacky 64199481Srdivacky void dump() { 65199481Srdivacky errs() << "MSP430ISelAddressMode " << this << '\n'; 66276479Sdim if (BaseType == RegBase && Base.Reg.getNode() != nullptr) { 67199481Srdivacky errs() << "Base.Reg "; 68199481Srdivacky Base.Reg.getNode()->dump(); 69200581Srdivacky } else if (BaseType == FrameIndexBase) { 70199481Srdivacky errs() << " Base.FrameIndex " << Base.FrameIndex << '\n'; 71199481Srdivacky } 72199481Srdivacky errs() << " Disp " << Disp << '\n'; 73199481Srdivacky if (GV) { 74199481Srdivacky errs() << "GV "; 75199481Srdivacky GV->dump(); 76199481Srdivacky } else if (CP) { 77199481Srdivacky errs() << " CP "; 78199481Srdivacky CP->dump(); 79199481Srdivacky errs() << " Align" << Align << '\n'; 80199481Srdivacky } else if (ES) { 81199481Srdivacky errs() << "ES "; 82199481Srdivacky errs() << ES << '\n'; 83199481Srdivacky } else if (JT != -1) 84199481Srdivacky errs() << " JT" << JT << " Align" << Align << '\n'; 85199481Srdivacky } 86199481Srdivacky }; 87199481Srdivacky} 88199481Srdivacky 89193323Sed/// MSP430DAGToDAGISel - MSP430 specific code to select MSP430 machine 90193323Sed/// instructions for SelectionDAG operations. 91193323Sed/// 92193323Sednamespace { 93193323Sed class MSP430DAGToDAGISel : public SelectionDAGISel { 94193323Sed public: 95193323Sed MSP430DAGToDAGISel(MSP430TargetMachine &TM, CodeGenOpt::Level OptLevel) 96288943Sdim : SelectionDAGISel(TM, OptLevel) {} 97193323Sed 98276479Sdim const char *getPassName() const override { 99193323Sed return "MSP430 DAG->DAG Pattern Instruction Selection"; 100193323Sed } 101193323Sed 102199481Srdivacky bool MatchAddress(SDValue N, MSP430ISelAddressMode &AM); 103199481Srdivacky bool MatchWrapper(SDValue N, MSP430ISelAddressMode &AM); 104199481Srdivacky bool MatchAddressBase(SDValue N, MSP430ISelAddressMode &AM); 105199481Srdivacky 106288943Sdim bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID, 107276479Sdim std::vector<SDValue> &OutOps) override; 108198090Srdivacky 109193323Sed // Include the pieces autogenerated from the target description. 110193323Sed #include "MSP430GenDAGISel.inc" 111193323Sed 112193323Sed private: 113309124Sdim void Select(SDNode *N) override; 114309124Sdim bool tryIndexedLoad(SDNode *Op); 115309124Sdim bool tryIndexedBinOp(SDNode *Op, SDValue N1, SDValue N2, unsigned Opc8, 116309124Sdim unsigned Opc16); 117199481Srdivacky 118218893Sdim bool SelectAddr(SDValue Addr, SDValue &Base, SDValue &Disp); 119193323Sed }; 120193323Sed} // end anonymous namespace 121193323Sed 122193323Sed/// createMSP430ISelDag - This pass converts a legalized DAG into a 123193323Sed/// MSP430-specific DAG, ready for instruction scheduling. 124193323Sed/// 125193323SedFunctionPass *llvm::createMSP430ISelDag(MSP430TargetMachine &TM, 126193323Sed CodeGenOpt::Level OptLevel) { 127193323Sed return new MSP430DAGToDAGISel(TM, OptLevel); 128193323Sed} 129193323Sed 130199481Srdivacky 131199481Srdivacky/// MatchWrapper - Try to match MSP430ISD::Wrapper node into an addressing mode. 132199481Srdivacky/// These wrap things that will resolve down into a symbol reference. If no 133199481Srdivacky/// match is possible, this returns true, otherwise it returns false. 134199481Srdivackybool MSP430DAGToDAGISel::MatchWrapper(SDValue N, MSP430ISelAddressMode &AM) { 135199481Srdivacky // If the addressing mode already has a symbol as the displacement, we can 136199481Srdivacky // never match another symbol. 137199481Srdivacky if (AM.hasSymbolicDisplacement()) 138193323Sed return true; 139199481Srdivacky 140199481Srdivacky SDValue N0 = N.getOperand(0); 141199481Srdivacky 142199481Srdivacky if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(N0)) { 143199481Srdivacky AM.GV = G->getGlobal(); 144199481Srdivacky AM.Disp += G->getOffset(); 145199481Srdivacky //AM.SymbolFlags = G->getTargetFlags(); 146199481Srdivacky } else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(N0)) { 147199481Srdivacky AM.CP = CP->getConstVal(); 148199481Srdivacky AM.Align = CP->getAlignment(); 149199481Srdivacky AM.Disp += CP->getOffset(); 150199481Srdivacky //AM.SymbolFlags = CP->getTargetFlags(); 151199481Srdivacky } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(N0)) { 152199481Srdivacky AM.ES = S->getSymbol(); 153199481Srdivacky //AM.SymbolFlags = S->getTargetFlags(); 154199481Srdivacky } else if (JumpTableSDNode *J = dyn_cast<JumpTableSDNode>(N0)) { 155199481Srdivacky AM.JT = J->getIndex(); 156199481Srdivacky //AM.SymbolFlags = J->getTargetFlags(); 157199481Srdivacky } else { 158199481Srdivacky AM.BlockAddr = cast<BlockAddressSDNode>(N0)->getBlockAddress(); 159199481Srdivacky //AM.SymbolFlags = cast<BlockAddressSDNode>(N0)->getTargetFlags(); 160193323Sed } 161199481Srdivacky return false; 162199481Srdivacky} 163193323Sed 164199481Srdivacky/// MatchAddressBase - Helper for MatchAddress. Add the specified node to the 165199481Srdivacky/// specified addressing mode without any further recursion. 166199481Srdivackybool MSP430DAGToDAGISel::MatchAddressBase(SDValue N, MSP430ISelAddressMode &AM) { 167199481Srdivacky // Is the base register already occupied? 168199481Srdivacky if (AM.BaseType != MSP430ISelAddressMode::RegBase || AM.Base.Reg.getNode()) { 169199481Srdivacky // If so, we cannot select it. 170199481Srdivacky return true; 171199481Srdivacky } 172193323Sed 173199481Srdivacky // Default, generate it as a register. 174199481Srdivacky AM.BaseType = MSP430ISelAddressMode::RegBase; 175199481Srdivacky AM.Base.Reg = N; 176199481Srdivacky return false; 177199481Srdivacky} 178199481Srdivacky 179199481Srdivackybool MSP430DAGToDAGISel::MatchAddress(SDValue N, MSP430ISelAddressMode &AM) { 180204642Srdivacky DEBUG(errs() << "MatchAddress: "; AM.dump()); 181199481Srdivacky 182199481Srdivacky switch (N.getOpcode()) { 183199481Srdivacky default: break; 184199481Srdivacky case ISD::Constant: { 185199481Srdivacky uint64_t Val = cast<ConstantSDNode>(N)->getSExtValue(); 186199481Srdivacky AM.Disp += Val; 187199481Srdivacky return false; 188199481Srdivacky } 189199481Srdivacky 190199481Srdivacky case MSP430ISD::Wrapper: 191199481Srdivacky if (!MatchWrapper(N, AM)) 192199481Srdivacky return false; 193199481Srdivacky break; 194199481Srdivacky 195199481Srdivacky case ISD::FrameIndex: 196199481Srdivacky if (AM.BaseType == MSP430ISelAddressMode::RegBase 197276479Sdim && AM.Base.Reg.getNode() == nullptr) { 198199481Srdivacky AM.BaseType = MSP430ISelAddressMode::FrameIndexBase; 199199481Srdivacky AM.Base.FrameIndex = cast<FrameIndexSDNode>(N)->getIndex(); 200199481Srdivacky return false; 201193323Sed } 202193323Sed break; 203199481Srdivacky 204199481Srdivacky case ISD::ADD: { 205199481Srdivacky MSP430ISelAddressMode Backup = AM; 206199481Srdivacky if (!MatchAddress(N.getNode()->getOperand(0), AM) && 207199481Srdivacky !MatchAddress(N.getNode()->getOperand(1), AM)) 208199481Srdivacky return false; 209199481Srdivacky AM = Backup; 210199481Srdivacky if (!MatchAddress(N.getNode()->getOperand(1), AM) && 211199481Srdivacky !MatchAddress(N.getNode()->getOperand(0), AM)) 212199481Srdivacky return false; 213199481Srdivacky AM = Backup; 214199481Srdivacky 215199481Srdivacky break; 216199481Srdivacky } 217199481Srdivacky 218199481Srdivacky case ISD::OR: 219199481Srdivacky // Handle "X | C" as "X + C" iff X is known to have C bits clear. 220199481Srdivacky if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 221199481Srdivacky MSP430ISelAddressMode Backup = AM; 222199481Srdivacky uint64_t Offset = CN->getSExtValue(); 223199481Srdivacky // Start with the LHS as an addr mode. 224199481Srdivacky if (!MatchAddress(N.getOperand(0), AM) && 225199481Srdivacky // Address could not have picked a GV address for the displacement. 226276479Sdim AM.GV == nullptr && 227199481Srdivacky // Check to see if the LHS & C is zero. 228199481Srdivacky CurDAG->MaskedValueIsZero(N.getOperand(0), CN->getAPIntValue())) { 229199481Srdivacky AM.Disp += Offset; 230199481Srdivacky return false; 231199481Srdivacky } 232199481Srdivacky AM = Backup; 233193323Sed } 234193323Sed break; 235199481Srdivacky } 236193323Sed 237199481Srdivacky return MatchAddressBase(N, AM); 238199481Srdivacky} 239193323Sed 240199481Srdivacky/// SelectAddr - returns true if it is able pattern match an addressing mode. 241199481Srdivacky/// It returns the operands which make up the maximal addressing mode it can 242199481Srdivacky/// match by reference. 243218893Sdimbool MSP430DAGToDAGISel::SelectAddr(SDValue N, 244199481Srdivacky SDValue &Base, SDValue &Disp) { 245199481Srdivacky MSP430ISelAddressMode AM; 246199481Srdivacky 247199481Srdivacky if (MatchAddress(N, AM)) 248199481Srdivacky return false; 249199481Srdivacky 250199481Srdivacky EVT VT = N.getValueType(); 251199481Srdivacky if (AM.BaseType == MSP430ISelAddressMode::RegBase) { 252199481Srdivacky if (!AM.Base.Reg.getNode()) 253199481Srdivacky AM.Base.Reg = CurDAG->getRegister(0, VT); 254199481Srdivacky } 255199481Srdivacky 256288943Sdim Base = (AM.BaseType == MSP430ISelAddressMode::FrameIndexBase) 257288943Sdim ? CurDAG->getTargetFrameIndex( 258288943Sdim AM.Base.FrameIndex, 259288943Sdim getTargetLowering()->getPointerTy(CurDAG->getDataLayout())) 260288943Sdim : AM.Base.Reg; 261199481Srdivacky 262199481Srdivacky if (AM.GV) 263261991Sdim Disp = CurDAG->getTargetGlobalAddress(AM.GV, SDLoc(N), 264210299Sed MVT::i16, AM.Disp, 265199481Srdivacky 0/*AM.SymbolFlags*/); 266199481Srdivacky else if (AM.CP) 267199481Srdivacky Disp = CurDAG->getTargetConstantPool(AM.CP, MVT::i16, 268199481Srdivacky AM.Align, AM.Disp, 0/*AM.SymbolFlags*/); 269199481Srdivacky else if (AM.ES) 270199481Srdivacky Disp = CurDAG->getTargetExternalSymbol(AM.ES, MVT::i16, 0/*AM.SymbolFlags*/); 271199481Srdivacky else if (AM.JT != -1) 272199481Srdivacky Disp = CurDAG->getTargetJumpTable(AM.JT, MVT::i16, 0/*AM.SymbolFlags*/); 273199481Srdivacky else if (AM.BlockAddr) 274243830Sdim Disp = CurDAG->getTargetBlockAddress(AM.BlockAddr, MVT::i32, 0, 275243830Sdim 0/*AM.SymbolFlags*/); 276199481Srdivacky else 277288943Sdim Disp = CurDAG->getTargetConstant(AM.Disp, SDLoc(N), MVT::i16); 278199481Srdivacky 279193323Sed return true; 280193323Sed} 281193323Sed 282198090Srdivackybool MSP430DAGToDAGISel:: 283288943SdimSelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID, 284198090Srdivacky std::vector<SDValue> &OutOps) { 285198090Srdivacky SDValue Op0, Op1; 286288943Sdim switch (ConstraintID) { 287198090Srdivacky default: return true; 288288943Sdim case InlineAsm::Constraint_m: // memory 289218893Sdim if (!SelectAddr(Op, Op0, Op1)) 290198090Srdivacky return true; 291198090Srdivacky break; 292198090Srdivacky } 293193323Sed 294198090Srdivacky OutOps.push_back(Op0); 295198090Srdivacky OutOps.push_back(Op1); 296198090Srdivacky return false; 297198090Srdivacky} 298198090Srdivacky 299199481Srdivackystatic bool isValidIndexedLoad(const LoadSDNode *LD) { 300199481Srdivacky ISD::MemIndexedMode AM = LD->getAddressingMode(); 301199481Srdivacky if (AM != ISD::POST_INC || LD->getExtensionType() != ISD::NON_EXTLOAD) 302199481Srdivacky return false; 303199481Srdivacky 304199481Srdivacky EVT VT = LD->getMemoryVT(); 305199481Srdivacky 306199481Srdivacky switch (VT.getSimpleVT().SimpleTy) { 307199481Srdivacky case MVT::i8: 308199481Srdivacky // Sanity check 309199481Srdivacky if (cast<ConstantSDNode>(LD->getOffset())->getZExtValue() != 1) 310199481Srdivacky return false; 311199481Srdivacky 312199481Srdivacky break; 313199481Srdivacky case MVT::i16: 314199481Srdivacky // Sanity check 315199481Srdivacky if (cast<ConstantSDNode>(LD->getOffset())->getZExtValue() != 2) 316199481Srdivacky return false; 317199481Srdivacky 318199481Srdivacky break; 319199481Srdivacky default: 320199481Srdivacky return false; 321199481Srdivacky } 322199481Srdivacky 323199481Srdivacky return true; 324199481Srdivacky} 325199481Srdivacky 326309124Sdimbool MSP430DAGToDAGISel::tryIndexedLoad(SDNode *N) { 327202375Srdivacky LoadSDNode *LD = cast<LoadSDNode>(N); 328199481Srdivacky if (!isValidIndexedLoad(LD)) 329309124Sdim return false; 330199481Srdivacky 331199481Srdivacky MVT VT = LD->getMemoryVT().getSimpleVT(); 332199481Srdivacky 333199481Srdivacky unsigned Opcode = 0; 334199481Srdivacky switch (VT.SimpleTy) { 335199481Srdivacky case MVT::i8: 336199481Srdivacky Opcode = MSP430::MOV8rm_POST; 337199481Srdivacky break; 338199481Srdivacky case MVT::i16: 339199481Srdivacky Opcode = MSP430::MOV16rm_POST; 340199481Srdivacky break; 341199481Srdivacky default: 342309124Sdim return false; 343199481Srdivacky } 344199481Srdivacky 345309124Sdim ReplaceNode(N, 346309124Sdim CurDAG->getMachineNode(Opcode, SDLoc(N), VT, MVT::i16, MVT::Other, 347309124Sdim LD->getBasePtr(), LD->getChain())); 348309124Sdim return true; 349199481Srdivacky} 350199481Srdivacky 351309124Sdimbool MSP430DAGToDAGISel::tryIndexedBinOp(SDNode *Op, SDValue N1, SDValue N2, 352309124Sdim unsigned Opc8, unsigned Opc16) { 353199481Srdivacky if (N1.getOpcode() == ISD::LOAD && 354199481Srdivacky N1.hasOneUse() && 355207618Srdivacky IsLegalToFold(N1, Op, Op, OptLevel)) { 356199481Srdivacky LoadSDNode *LD = cast<LoadSDNode>(N1); 357199481Srdivacky if (!isValidIndexedLoad(LD)) 358309124Sdim return false; 359199481Srdivacky 360199481Srdivacky MVT VT = LD->getMemoryVT().getSimpleVT(); 361199481Srdivacky unsigned Opc = (VT == MVT::i16 ? Opc16 : Opc8); 362199481Srdivacky MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1); 363199481Srdivacky MemRefs0[0] = cast<MemSDNode>(N1)->getMemOperand(); 364199481Srdivacky SDValue Ops0[] = { N2, LD->getBasePtr(), LD->getChain() }; 365199481Srdivacky SDNode *ResNode = 366276479Sdim CurDAG->SelectNodeTo(Op, Opc, VT, MVT::i16, MVT::Other, Ops0); 367199481Srdivacky cast<MachineSDNode>(ResNode)->setMemRefs(MemRefs0, MemRefs0 + 1); 368199481Srdivacky // Transfer chain. 369199481Srdivacky ReplaceUses(SDValue(N1.getNode(), 2), SDValue(ResNode, 2)); 370199481Srdivacky // Transfer writeback. 371199481Srdivacky ReplaceUses(SDValue(N1.getNode(), 1), SDValue(ResNode, 1)); 372309124Sdim return true; 373199481Srdivacky } 374199481Srdivacky 375309124Sdim return false; 376199481Srdivacky} 377199481Srdivacky 378199481Srdivacky 379309124Sdimvoid MSP430DAGToDAGISel::Select(SDNode *Node) { 380261991Sdim SDLoc dl(Node); 381193323Sed 382193323Sed // Dump information about the Node being selected 383204642Srdivacky DEBUG(errs() << "Selecting: "); 384193323Sed DEBUG(Node->dump(CurDAG)); 385198090Srdivacky DEBUG(errs() << "\n"); 386193323Sed 387193323Sed // If we have a custom node, we already have selected! 388193323Sed if (Node->isMachineOpcode()) { 389204642Srdivacky DEBUG(errs() << "== "; 390198090Srdivacky Node->dump(CurDAG); 391198090Srdivacky errs() << "\n"); 392255804Sdim Node->setNodeId(-1); 393309124Sdim return; 394193323Sed } 395193323Sed 396193323Sed // Few custom selection stuff. 397193323Sed switch (Node->getOpcode()) { 398193323Sed default: break; 399193323Sed case ISD::FrameIndex: { 400202375Srdivacky assert(Node->getValueType(0) == MVT::i16); 401193323Sed int FI = cast<FrameIndexSDNode>(Node)->getIndex(); 402193323Sed SDValue TFI = CurDAG->getTargetFrameIndex(FI, MVT::i16); 403309124Sdim if (Node->hasOneUse()) { 404309124Sdim CurDAG->SelectNodeTo(Node, MSP430::ADD16ri, MVT::i16, TFI, 405309124Sdim CurDAG->getTargetConstant(0, dl, MVT::i16)); 406309124Sdim return; 407309124Sdim } 408309124Sdim ReplaceNode(Node, CurDAG->getMachineNode( 409309124Sdim MSP430::ADD16ri, dl, MVT::i16, TFI, 410309124Sdim CurDAG->getTargetConstant(0, dl, MVT::i16))); 411309124Sdim return; 412193323Sed } 413199481Srdivacky case ISD::LOAD: 414309124Sdim if (tryIndexedLoad(Node)) 415309124Sdim return; 416199481Srdivacky // Other cases are autogenerated. 417199481Srdivacky break; 418199481Srdivacky case ISD::ADD: 419309124Sdim if (tryIndexedBinOp(Node, Node->getOperand(0), Node->getOperand(1), 420309124Sdim MSP430::ADD8rm_POST, MSP430::ADD16rm_POST)) 421309124Sdim return; 422309124Sdim else if (tryIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0), 423309124Sdim MSP430::ADD8rm_POST, MSP430::ADD16rm_POST)) 424309124Sdim return; 425199481Srdivacky 426199481Srdivacky // Other cases are autogenerated. 427199481Srdivacky break; 428199481Srdivacky case ISD::SUB: 429309124Sdim if (tryIndexedBinOp(Node, Node->getOperand(0), Node->getOperand(1), 430309124Sdim MSP430::SUB8rm_POST, MSP430::SUB16rm_POST)) 431309124Sdim return; 432199481Srdivacky 433199481Srdivacky // Other cases are autogenerated. 434199481Srdivacky break; 435199481Srdivacky case ISD::AND: 436309124Sdim if (tryIndexedBinOp(Node, Node->getOperand(0), Node->getOperand(1), 437309124Sdim MSP430::AND8rm_POST, MSP430::AND16rm_POST)) 438309124Sdim return; 439309124Sdim else if (tryIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0), 440309124Sdim MSP430::AND8rm_POST, MSP430::AND16rm_POST)) 441309124Sdim return; 442199481Srdivacky 443199481Srdivacky // Other cases are autogenerated. 444199481Srdivacky break; 445199481Srdivacky case ISD::OR: 446309124Sdim if (tryIndexedBinOp(Node, Node->getOperand(0), Node->getOperand(1), 447309124Sdim MSP430::OR8rm_POST, MSP430::OR16rm_POST)) 448309124Sdim return; 449309124Sdim else if (tryIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0), 450309124Sdim MSP430::OR8rm_POST, MSP430::OR16rm_POST)) 451309124Sdim return; 452199481Srdivacky 453199481Srdivacky // Other cases are autogenerated. 454199481Srdivacky break; 455199481Srdivacky case ISD::XOR: 456309124Sdim if (tryIndexedBinOp(Node, Node->getOperand(0), Node->getOperand(1), 457309124Sdim MSP430::XOR8rm_POST, MSP430::XOR16rm_POST)) 458309124Sdim return; 459309124Sdim else if (tryIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0), 460309124Sdim MSP430::XOR8rm_POST, MSP430::XOR16rm_POST)) 461309124Sdim return; 462199481Srdivacky 463199481Srdivacky // Other cases are autogenerated. 464199481Srdivacky break; 465193323Sed } 466193323Sed 467193323Sed // Select the default instruction 468309124Sdim SelectCode(Node); 469193323Sed} 470