LLVM API Documentation
00001 //===-- MSP430ISelDAGToDAG.cpp - A dag to dag inst selector for MSP430 ----===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines an instruction selector for the MSP430 target. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "MSP430.h" 00015 #include "MSP430TargetMachine.h" 00016 #include "llvm/CodeGen/MachineFrameInfo.h" 00017 #include "llvm/CodeGen/MachineFunction.h" 00018 #include "llvm/CodeGen/MachineInstrBuilder.h" 00019 #include "llvm/CodeGen/MachineRegisterInfo.h" 00020 #include "llvm/CodeGen/SelectionDAG.h" 00021 #include "llvm/CodeGen/SelectionDAGISel.h" 00022 #include "llvm/IR/CallingConv.h" 00023 #include "llvm/IR/Constants.h" 00024 #include "llvm/IR/DerivedTypes.h" 00025 #include "llvm/IR/Function.h" 00026 #include "llvm/IR/Intrinsics.h" 00027 #include "llvm/Support/Compiler.h" 00028 #include "llvm/Support/Debug.h" 00029 #include "llvm/Support/ErrorHandling.h" 00030 #include "llvm/Support/raw_ostream.h" 00031 #include "llvm/Target/TargetLowering.h" 00032 using namespace llvm; 00033 00034 #define DEBUG_TYPE "msp430-isel" 00035 00036 namespace { 00037 struct MSP430ISelAddressMode { 00038 enum { 00039 RegBase, 00040 FrameIndexBase 00041 } BaseType; 00042 00043 struct { // This is really a union, discriminated by BaseType! 00044 SDValue Reg; 00045 int FrameIndex; 00046 } Base; 00047 00048 int16_t Disp; 00049 const GlobalValue *GV; 00050 const Constant *CP; 00051 const BlockAddress *BlockAddr; 00052 const char *ES; 00053 int JT; 00054 unsigned Align; // CP alignment. 00055 00056 MSP430ISelAddressMode() 00057 : BaseType(RegBase), Disp(0), GV(nullptr), CP(nullptr), 00058 BlockAddr(nullptr), ES(nullptr), JT(-1), Align(0) { 00059 } 00060 00061 bool hasSymbolicDisplacement() const { 00062 return GV != nullptr || CP != nullptr || ES != nullptr || JT != -1; 00063 } 00064 00065 void dump() { 00066 errs() << "MSP430ISelAddressMode " << this << '\n'; 00067 if (BaseType == RegBase && Base.Reg.getNode() != nullptr) { 00068 errs() << "Base.Reg "; 00069 Base.Reg.getNode()->dump(); 00070 } else if (BaseType == FrameIndexBase) { 00071 errs() << " Base.FrameIndex " << Base.FrameIndex << '\n'; 00072 } 00073 errs() << " Disp " << Disp << '\n'; 00074 if (GV) { 00075 errs() << "GV "; 00076 GV->dump(); 00077 } else if (CP) { 00078 errs() << " CP "; 00079 CP->dump(); 00080 errs() << " Align" << Align << '\n'; 00081 } else if (ES) { 00082 errs() << "ES "; 00083 errs() << ES << '\n'; 00084 } else if (JT != -1) 00085 errs() << " JT" << JT << " Align" << Align << '\n'; 00086 } 00087 }; 00088 } 00089 00090 /// MSP430DAGToDAGISel - MSP430 specific code to select MSP430 machine 00091 /// instructions for SelectionDAG operations. 00092 /// 00093 namespace { 00094 class MSP430DAGToDAGISel : public SelectionDAGISel { 00095 const MSP430TargetLowering &Lowering; 00096 const MSP430Subtarget &Subtarget; 00097 00098 public: 00099 MSP430DAGToDAGISel(MSP430TargetMachine &TM, CodeGenOpt::Level OptLevel) 00100 : SelectionDAGISel(TM, OptLevel), 00101 Lowering(*TM.getSubtargetImpl()->getTargetLowering()), 00102 Subtarget(*TM.getSubtargetImpl()) {} 00103 00104 const char *getPassName() const override { 00105 return "MSP430 DAG->DAG Pattern Instruction Selection"; 00106 } 00107 00108 bool MatchAddress(SDValue N, MSP430ISelAddressMode &AM); 00109 bool MatchWrapper(SDValue N, MSP430ISelAddressMode &AM); 00110 bool MatchAddressBase(SDValue N, MSP430ISelAddressMode &AM); 00111 00112 bool SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, 00113 std::vector<SDValue> &OutOps) override; 00114 00115 // Include the pieces autogenerated from the target description. 00116 #include "MSP430GenDAGISel.inc" 00117 00118 private: 00119 SDNode *Select(SDNode *N) override; 00120 SDNode *SelectIndexedLoad(SDNode *Op); 00121 SDNode *SelectIndexedBinOp(SDNode *Op, SDValue N1, SDValue N2, 00122 unsigned Opc8, unsigned Opc16); 00123 00124 bool SelectAddr(SDValue Addr, SDValue &Base, SDValue &Disp); 00125 }; 00126 } // end anonymous namespace 00127 00128 /// createMSP430ISelDag - This pass converts a legalized DAG into a 00129 /// MSP430-specific DAG, ready for instruction scheduling. 00130 /// 00131 FunctionPass *llvm::createMSP430ISelDag(MSP430TargetMachine &TM, 00132 CodeGenOpt::Level OptLevel) { 00133 return new MSP430DAGToDAGISel(TM, OptLevel); 00134 } 00135 00136 00137 /// MatchWrapper - Try to match MSP430ISD::Wrapper node into an addressing mode. 00138 /// These wrap things that will resolve down into a symbol reference. If no 00139 /// match is possible, this returns true, otherwise it returns false. 00140 bool MSP430DAGToDAGISel::MatchWrapper(SDValue N, MSP430ISelAddressMode &AM) { 00141 // If the addressing mode already has a symbol as the displacement, we can 00142 // never match another symbol. 00143 if (AM.hasSymbolicDisplacement()) 00144 return true; 00145 00146 SDValue N0 = N.getOperand(0); 00147 00148 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(N0)) { 00149 AM.GV = G->getGlobal(); 00150 AM.Disp += G->getOffset(); 00151 //AM.SymbolFlags = G->getTargetFlags(); 00152 } else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(N0)) { 00153 AM.CP = CP->getConstVal(); 00154 AM.Align = CP->getAlignment(); 00155 AM.Disp += CP->getOffset(); 00156 //AM.SymbolFlags = CP->getTargetFlags(); 00157 } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(N0)) { 00158 AM.ES = S->getSymbol(); 00159 //AM.SymbolFlags = S->getTargetFlags(); 00160 } else if (JumpTableSDNode *J = dyn_cast<JumpTableSDNode>(N0)) { 00161 AM.JT = J->getIndex(); 00162 //AM.SymbolFlags = J->getTargetFlags(); 00163 } else { 00164 AM.BlockAddr = cast<BlockAddressSDNode>(N0)->getBlockAddress(); 00165 //AM.SymbolFlags = cast<BlockAddressSDNode>(N0)->getTargetFlags(); 00166 } 00167 return false; 00168 } 00169 00170 /// MatchAddressBase - Helper for MatchAddress. Add the specified node to the 00171 /// specified addressing mode without any further recursion. 00172 bool MSP430DAGToDAGISel::MatchAddressBase(SDValue N, MSP430ISelAddressMode &AM) { 00173 // Is the base register already occupied? 00174 if (AM.BaseType != MSP430ISelAddressMode::RegBase || AM.Base.Reg.getNode()) { 00175 // If so, we cannot select it. 00176 return true; 00177 } 00178 00179 // Default, generate it as a register. 00180 AM.BaseType = MSP430ISelAddressMode::RegBase; 00181 AM.Base.Reg = N; 00182 return false; 00183 } 00184 00185 bool MSP430DAGToDAGISel::MatchAddress(SDValue N, MSP430ISelAddressMode &AM) { 00186 DEBUG(errs() << "MatchAddress: "; AM.dump()); 00187 00188 switch (N.getOpcode()) { 00189 default: break; 00190 case ISD::Constant: { 00191 uint64_t Val = cast<ConstantSDNode>(N)->getSExtValue(); 00192 AM.Disp += Val; 00193 return false; 00194 } 00195 00196 case MSP430ISD::Wrapper: 00197 if (!MatchWrapper(N, AM)) 00198 return false; 00199 break; 00200 00201 case ISD::FrameIndex: 00202 if (AM.BaseType == MSP430ISelAddressMode::RegBase 00203 && AM.Base.Reg.getNode() == nullptr) { 00204 AM.BaseType = MSP430ISelAddressMode::FrameIndexBase; 00205 AM.Base.FrameIndex = cast<FrameIndexSDNode>(N)->getIndex(); 00206 return false; 00207 } 00208 break; 00209 00210 case ISD::ADD: { 00211 MSP430ISelAddressMode Backup = AM; 00212 if (!MatchAddress(N.getNode()->getOperand(0), AM) && 00213 !MatchAddress(N.getNode()->getOperand(1), AM)) 00214 return false; 00215 AM = Backup; 00216 if (!MatchAddress(N.getNode()->getOperand(1), AM) && 00217 !MatchAddress(N.getNode()->getOperand(0), AM)) 00218 return false; 00219 AM = Backup; 00220 00221 break; 00222 } 00223 00224 case ISD::OR: 00225 // Handle "X | C" as "X + C" iff X is known to have C bits clear. 00226 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 00227 MSP430ISelAddressMode Backup = AM; 00228 uint64_t Offset = CN->getSExtValue(); 00229 // Start with the LHS as an addr mode. 00230 if (!MatchAddress(N.getOperand(0), AM) && 00231 // Address could not have picked a GV address for the displacement. 00232 AM.GV == nullptr && 00233 // Check to see if the LHS & C is zero. 00234 CurDAG->MaskedValueIsZero(N.getOperand(0), CN->getAPIntValue())) { 00235 AM.Disp += Offset; 00236 return false; 00237 } 00238 AM = Backup; 00239 } 00240 break; 00241 } 00242 00243 return MatchAddressBase(N, AM); 00244 } 00245 00246 /// SelectAddr - returns true if it is able pattern match an addressing mode. 00247 /// It returns the operands which make up the maximal addressing mode it can 00248 /// match by reference. 00249 bool MSP430DAGToDAGISel::SelectAddr(SDValue N, 00250 SDValue &Base, SDValue &Disp) { 00251 MSP430ISelAddressMode AM; 00252 00253 if (MatchAddress(N, AM)) 00254 return false; 00255 00256 EVT VT = N.getValueType(); 00257 if (AM.BaseType == MSP430ISelAddressMode::RegBase) { 00258 if (!AM.Base.Reg.getNode()) 00259 AM.Base.Reg = CurDAG->getRegister(0, VT); 00260 } 00261 00262 Base = (AM.BaseType == MSP430ISelAddressMode::FrameIndexBase) ? 00263 CurDAG->getTargetFrameIndex(AM.Base.FrameIndex, 00264 getTargetLowering()->getPointerTy()) : 00265 AM.Base.Reg; 00266 00267 if (AM.GV) 00268 Disp = CurDAG->getTargetGlobalAddress(AM.GV, SDLoc(N), 00269 MVT::i16, AM.Disp, 00270 0/*AM.SymbolFlags*/); 00271 else if (AM.CP) 00272 Disp = CurDAG->getTargetConstantPool(AM.CP, MVT::i16, 00273 AM.Align, AM.Disp, 0/*AM.SymbolFlags*/); 00274 else if (AM.ES) 00275 Disp = CurDAG->getTargetExternalSymbol(AM.ES, MVT::i16, 0/*AM.SymbolFlags*/); 00276 else if (AM.JT != -1) 00277 Disp = CurDAG->getTargetJumpTable(AM.JT, MVT::i16, 0/*AM.SymbolFlags*/); 00278 else if (AM.BlockAddr) 00279 Disp = CurDAG->getTargetBlockAddress(AM.BlockAddr, MVT::i32, 0, 00280 0/*AM.SymbolFlags*/); 00281 else 00282 Disp = CurDAG->getTargetConstant(AM.Disp, MVT::i16); 00283 00284 return true; 00285 } 00286 00287 bool MSP430DAGToDAGISel:: 00288 SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, 00289 std::vector<SDValue> &OutOps) { 00290 SDValue Op0, Op1; 00291 switch (ConstraintCode) { 00292 default: return true; 00293 case 'm': // memory 00294 if (!SelectAddr(Op, Op0, Op1)) 00295 return true; 00296 break; 00297 } 00298 00299 OutOps.push_back(Op0); 00300 OutOps.push_back(Op1); 00301 return false; 00302 } 00303 00304 static bool isValidIndexedLoad(const LoadSDNode *LD) { 00305 ISD::MemIndexedMode AM = LD->getAddressingMode(); 00306 if (AM != ISD::POST_INC || LD->getExtensionType() != ISD::NON_EXTLOAD) 00307 return false; 00308 00309 EVT VT = LD->getMemoryVT(); 00310 00311 switch (VT.getSimpleVT().SimpleTy) { 00312 case MVT::i8: 00313 // Sanity check 00314 if (cast<ConstantSDNode>(LD->getOffset())->getZExtValue() != 1) 00315 return false; 00316 00317 break; 00318 case MVT::i16: 00319 // Sanity check 00320 if (cast<ConstantSDNode>(LD->getOffset())->getZExtValue() != 2) 00321 return false; 00322 00323 break; 00324 default: 00325 return false; 00326 } 00327 00328 return true; 00329 } 00330 00331 SDNode *MSP430DAGToDAGISel::SelectIndexedLoad(SDNode *N) { 00332 LoadSDNode *LD = cast<LoadSDNode>(N); 00333 if (!isValidIndexedLoad(LD)) 00334 return nullptr; 00335 00336 MVT VT = LD->getMemoryVT().getSimpleVT(); 00337 00338 unsigned Opcode = 0; 00339 switch (VT.SimpleTy) { 00340 case MVT::i8: 00341 Opcode = MSP430::MOV8rm_POST; 00342 break; 00343 case MVT::i16: 00344 Opcode = MSP430::MOV16rm_POST; 00345 break; 00346 default: 00347 return nullptr; 00348 } 00349 00350 return CurDAG->getMachineNode(Opcode, SDLoc(N), 00351 VT, MVT::i16, MVT::Other, 00352 LD->getBasePtr(), LD->getChain()); 00353 } 00354 00355 SDNode *MSP430DAGToDAGISel::SelectIndexedBinOp(SDNode *Op, 00356 SDValue N1, SDValue N2, 00357 unsigned Opc8, unsigned Opc16) { 00358 if (N1.getOpcode() == ISD::LOAD && 00359 N1.hasOneUse() && 00360 IsLegalToFold(N1, Op, Op, OptLevel)) { 00361 LoadSDNode *LD = cast<LoadSDNode>(N1); 00362 if (!isValidIndexedLoad(LD)) 00363 return nullptr; 00364 00365 MVT VT = LD->getMemoryVT().getSimpleVT(); 00366 unsigned Opc = (VT == MVT::i16 ? Opc16 : Opc8); 00367 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1); 00368 MemRefs0[0] = cast<MemSDNode>(N1)->getMemOperand(); 00369 SDValue Ops0[] = { N2, LD->getBasePtr(), LD->getChain() }; 00370 SDNode *ResNode = 00371 CurDAG->SelectNodeTo(Op, Opc, VT, MVT::i16, MVT::Other, Ops0); 00372 cast<MachineSDNode>(ResNode)->setMemRefs(MemRefs0, MemRefs0 + 1); 00373 // Transfer chain. 00374 ReplaceUses(SDValue(N1.getNode(), 2), SDValue(ResNode, 2)); 00375 // Transfer writeback. 00376 ReplaceUses(SDValue(N1.getNode(), 1), SDValue(ResNode, 1)); 00377 return ResNode; 00378 } 00379 00380 return nullptr; 00381 } 00382 00383 00384 SDNode *MSP430DAGToDAGISel::Select(SDNode *Node) { 00385 SDLoc dl(Node); 00386 00387 // Dump information about the Node being selected 00388 DEBUG(errs() << "Selecting: "); 00389 DEBUG(Node->dump(CurDAG)); 00390 DEBUG(errs() << "\n"); 00391 00392 // If we have a custom node, we already have selected! 00393 if (Node->isMachineOpcode()) { 00394 DEBUG(errs() << "== "; 00395 Node->dump(CurDAG); 00396 errs() << "\n"); 00397 Node->setNodeId(-1); 00398 return nullptr; 00399 } 00400 00401 // Few custom selection stuff. 00402 switch (Node->getOpcode()) { 00403 default: break; 00404 case ISD::FrameIndex: { 00405 assert(Node->getValueType(0) == MVT::i16); 00406 int FI = cast<FrameIndexSDNode>(Node)->getIndex(); 00407 SDValue TFI = CurDAG->getTargetFrameIndex(FI, MVT::i16); 00408 if (Node->hasOneUse()) 00409 return CurDAG->SelectNodeTo(Node, MSP430::ADD16ri, MVT::i16, 00410 TFI, CurDAG->getTargetConstant(0, MVT::i16)); 00411 return CurDAG->getMachineNode(MSP430::ADD16ri, dl, MVT::i16, 00412 TFI, CurDAG->getTargetConstant(0, MVT::i16)); 00413 } 00414 case ISD::LOAD: 00415 if (SDNode *ResNode = SelectIndexedLoad(Node)) 00416 return ResNode; 00417 // Other cases are autogenerated. 00418 break; 00419 case ISD::ADD: 00420 if (SDNode *ResNode = 00421 SelectIndexedBinOp(Node, 00422 Node->getOperand(0), Node->getOperand(1), 00423 MSP430::ADD8rm_POST, MSP430::ADD16rm_POST)) 00424 return ResNode; 00425 else if (SDNode *ResNode = 00426 SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0), 00427 MSP430::ADD8rm_POST, MSP430::ADD16rm_POST)) 00428 return ResNode; 00429 00430 // Other cases are autogenerated. 00431 break; 00432 case ISD::SUB: 00433 if (SDNode *ResNode = 00434 SelectIndexedBinOp(Node, 00435 Node->getOperand(0), Node->getOperand(1), 00436 MSP430::SUB8rm_POST, MSP430::SUB16rm_POST)) 00437 return ResNode; 00438 00439 // Other cases are autogenerated. 00440 break; 00441 case ISD::AND: 00442 if (SDNode *ResNode = 00443 SelectIndexedBinOp(Node, 00444 Node->getOperand(0), Node->getOperand(1), 00445 MSP430::AND8rm_POST, MSP430::AND16rm_POST)) 00446 return ResNode; 00447 else if (SDNode *ResNode = 00448 SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0), 00449 MSP430::AND8rm_POST, MSP430::AND16rm_POST)) 00450 return ResNode; 00451 00452 // Other cases are autogenerated. 00453 break; 00454 case ISD::OR: 00455 if (SDNode *ResNode = 00456 SelectIndexedBinOp(Node, 00457 Node->getOperand(0), Node->getOperand(1), 00458 MSP430::OR8rm_POST, MSP430::OR16rm_POST)) 00459 return ResNode; 00460 else if (SDNode *ResNode = 00461 SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0), 00462 MSP430::OR8rm_POST, MSP430::OR16rm_POST)) 00463 return ResNode; 00464 00465 // Other cases are autogenerated. 00466 break; 00467 case ISD::XOR: 00468 if (SDNode *ResNode = 00469 SelectIndexedBinOp(Node, 00470 Node->getOperand(0), Node->getOperand(1), 00471 MSP430::XOR8rm_POST, MSP430::XOR16rm_POST)) 00472 return ResNode; 00473 else if (SDNode *ResNode = 00474 SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0), 00475 MSP430::XOR8rm_POST, MSP430::XOR16rm_POST)) 00476 return ResNode; 00477 00478 // Other cases are autogenerated. 00479 break; 00480 } 00481 00482 // Select the default instruction 00483 SDNode *ResNode = SelectCode(Node); 00484 00485 DEBUG(errs() << "=> "); 00486 if (ResNode == nullptr || ResNode == Node) 00487 DEBUG(Node->dump(CurDAG)); 00488 else 00489 DEBUG(ResNode->dump(CurDAG)); 00490 DEBUG(errs() << "\n"); 00491 00492 return ResNode; 00493 }