LLVM API Documentation

MSP430ISelDAGToDAG.cpp
Go to the documentation of this file.
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 }