Home | History | Annotate | Download | only in MSP430
      1 //===-- MSP430ISelDAGToDAG.cpp - A dag to dag inst selector for MSP430 ----===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file defines an instruction selector for the MSP430 target.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "MSP430.h"
     15 #include "MSP430TargetMachine.h"
     16 #include "llvm/CodeGen/MachineFrameInfo.h"
     17 #include "llvm/CodeGen/MachineFunction.h"
     18 #include "llvm/CodeGen/MachineInstrBuilder.h"
     19 #include "llvm/CodeGen/MachineRegisterInfo.h"
     20 #include "llvm/CodeGen/SelectionDAG.h"
     21 #include "llvm/CodeGen/SelectionDAGISel.h"
     22 #include "llvm/IR/CallingConv.h"
     23 #include "llvm/IR/Constants.h"
     24 #include "llvm/IR/DerivedTypes.h"
     25 #include "llvm/IR/Function.h"
     26 #include "llvm/IR/Intrinsics.h"
     27 #include "llvm/Support/Compiler.h"
     28 #include "llvm/Support/Debug.h"
     29 #include "llvm/Support/ErrorHandling.h"
     30 #include "llvm/Support/raw_ostream.h"
     31 #include "llvm/Target/TargetLowering.h"
     32 using namespace llvm;
     33 
     34 #define DEBUG_TYPE "msp430-isel"
     35 
     36 namespace {
     37   struct MSP430ISelAddressMode {
     38     enum {
     39       RegBase,
     40       FrameIndexBase
     41     } BaseType;
     42 
     43     struct {            // This is really a union, discriminated by BaseType!
     44       SDValue Reg;
     45       int FrameIndex;
     46     } Base;
     47 
     48     int16_t Disp;
     49     const GlobalValue *GV;
     50     const Constant *CP;
     51     const BlockAddress *BlockAddr;
     52     const char *ES;
     53     int JT;
     54     unsigned Align;    // CP alignment.
     55 
     56     MSP430ISelAddressMode()
     57       : BaseType(RegBase), Disp(0), GV(nullptr), CP(nullptr),
     58         BlockAddr(nullptr), ES(nullptr), JT(-1), Align(0) {
     59     }
     60 
     61     bool hasSymbolicDisplacement() const {
     62       return GV != nullptr || CP != nullptr || ES != nullptr || JT != -1;
     63     }
     64 
     65     void dump() {
     66       errs() << "MSP430ISelAddressMode " << this << '\n';
     67       if (BaseType == RegBase && Base.Reg.getNode() != nullptr) {
     68         errs() << "Base.Reg ";
     69         Base.Reg.getNode()->dump();
     70       } else if (BaseType == FrameIndexBase) {
     71         errs() << " Base.FrameIndex " << Base.FrameIndex << '\n';
     72       }
     73       errs() << " Disp " << Disp << '\n';
     74       if (GV) {
     75         errs() << "GV ";
     76         GV->dump();
     77       } else if (CP) {
     78         errs() << " CP ";
     79         CP->dump();
     80         errs() << " Align" << Align << '\n';
     81       } else if (ES) {
     82         errs() << "ES ";
     83         errs() << ES << '\n';
     84       } else if (JT != -1)
     85         errs() << " JT" << JT << " Align" << Align << '\n';
     86     }
     87   };
     88 }
     89 
     90 /// MSP430DAGToDAGISel - MSP430 specific code to select MSP430 machine
     91 /// instructions for SelectionDAG operations.
     92 ///
     93 namespace {
     94   class MSP430DAGToDAGISel : public SelectionDAGISel {
     95     const MSP430TargetLowering &Lowering;
     96     const MSP430Subtarget &Subtarget;
     97 
     98   public:
     99     MSP430DAGToDAGISel(MSP430TargetMachine &TM, CodeGenOpt::Level OptLevel)
    100       : SelectionDAGISel(TM, OptLevel),
    101         Lowering(*TM.getTargetLowering()),
    102         Subtarget(*TM.getSubtargetImpl()) { }
    103 
    104     const char *getPassName() const override {
    105       return "MSP430 DAG->DAG Pattern Instruction Selection";
    106     }
    107 
    108     bool MatchAddress(SDValue N, MSP430ISelAddressMode &AM);
    109     bool MatchWrapper(SDValue N, MSP430ISelAddressMode &AM);
    110     bool MatchAddressBase(SDValue N, MSP430ISelAddressMode &AM);
    111 
    112     bool SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
    113                                       std::vector<SDValue> &OutOps) override;
    114 
    115     // Include the pieces autogenerated from the target description.
    116   #include "MSP430GenDAGISel.inc"
    117 
    118   private:
    119     SDNode *Select(SDNode *N) override;
    120     SDNode *SelectIndexedLoad(SDNode *Op);
    121     SDNode *SelectIndexedBinOp(SDNode *Op, SDValue N1, SDValue N2,
    122                                unsigned Opc8, unsigned Opc16);
    123 
    124     bool SelectAddr(SDValue Addr, SDValue &Base, SDValue &Disp);
    125   };
    126 }  // end anonymous namespace
    127 
    128 /// createMSP430ISelDag - This pass converts a legalized DAG into a
    129 /// MSP430-specific DAG, ready for instruction scheduling.
    130 ///
    131 FunctionPass *llvm::createMSP430ISelDag(MSP430TargetMachine &TM,
    132                                         CodeGenOpt::Level OptLevel) {
    133   return new MSP430DAGToDAGISel(TM, OptLevel);
    134 }
    135 
    136 
    137 /// MatchWrapper - Try to match MSP430ISD::Wrapper node into an addressing mode.
    138 /// These wrap things that will resolve down into a symbol reference.  If no
    139 /// match is possible, this returns true, otherwise it returns false.
    140 bool MSP430DAGToDAGISel::MatchWrapper(SDValue N, MSP430ISelAddressMode &AM) {
    141   // If the addressing mode already has a symbol as the displacement, we can
    142   // never match another symbol.
    143   if (AM.hasSymbolicDisplacement())
    144     return true;
    145 
    146   SDValue N0 = N.getOperand(0);
    147 
    148   if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(N0)) {
    149     AM.GV = G->getGlobal();
    150     AM.Disp += G->getOffset();
    151     //AM.SymbolFlags = G->getTargetFlags();
    152   } else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(N0)) {
    153     AM.CP = CP->getConstVal();
    154     AM.Align = CP->getAlignment();
    155     AM.Disp += CP->getOffset();
    156     //AM.SymbolFlags = CP->getTargetFlags();
    157   } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(N0)) {
    158     AM.ES = S->getSymbol();
    159     //AM.SymbolFlags = S->getTargetFlags();
    160   } else if (JumpTableSDNode *J = dyn_cast<JumpTableSDNode>(N0)) {
    161     AM.JT = J->getIndex();
    162     //AM.SymbolFlags = J->getTargetFlags();
    163   } else {
    164     AM.BlockAddr = cast<BlockAddressSDNode>(N0)->getBlockAddress();
    165     //AM.SymbolFlags = cast<BlockAddressSDNode>(N0)->getTargetFlags();
    166   }
    167   return false;
    168 }
    169 
    170 /// MatchAddressBase - Helper for MatchAddress. Add the specified node to the
    171 /// specified addressing mode without any further recursion.
    172 bool MSP430DAGToDAGISel::MatchAddressBase(SDValue N, MSP430ISelAddressMode &AM) {
    173   // Is the base register already occupied?
    174   if (AM.BaseType != MSP430ISelAddressMode::RegBase || AM.Base.Reg.getNode()) {
    175     // If so, we cannot select it.
    176     return true;
    177   }
    178 
    179   // Default, generate it as a register.
    180   AM.BaseType = MSP430ISelAddressMode::RegBase;
    181   AM.Base.Reg = N;
    182   return false;
    183 }
    184 
    185 bool MSP430DAGToDAGISel::MatchAddress(SDValue N, MSP430ISelAddressMode &AM) {
    186   DEBUG(errs() << "MatchAddress: "; AM.dump());
    187 
    188   switch (N.getOpcode()) {
    189   default: break;
    190   case ISD::Constant: {
    191     uint64_t Val = cast<ConstantSDNode>(N)->getSExtValue();
    192     AM.Disp += Val;
    193     return false;
    194   }
    195 
    196   case MSP430ISD::Wrapper:
    197     if (!MatchWrapper(N, AM))
    198       return false;
    199     break;
    200 
    201   case ISD::FrameIndex:
    202     if (AM.BaseType == MSP430ISelAddressMode::RegBase
    203         && AM.Base.Reg.getNode() == nullptr) {
    204       AM.BaseType = MSP430ISelAddressMode::FrameIndexBase;
    205       AM.Base.FrameIndex = cast<FrameIndexSDNode>(N)->getIndex();
    206       return false;
    207     }
    208     break;
    209 
    210   case ISD::ADD: {
    211     MSP430ISelAddressMode Backup = AM;
    212     if (!MatchAddress(N.getNode()->getOperand(0), AM) &&
    213         !MatchAddress(N.getNode()->getOperand(1), AM))
    214       return false;
    215     AM = Backup;
    216     if (!MatchAddress(N.getNode()->getOperand(1), AM) &&
    217         !MatchAddress(N.getNode()->getOperand(0), AM))
    218       return false;
    219     AM = Backup;
    220 
    221     break;
    222   }
    223 
    224   case ISD::OR:
    225     // Handle "X | C" as "X + C" iff X is known to have C bits clear.
    226     if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
    227       MSP430ISelAddressMode Backup = AM;
    228       uint64_t Offset = CN->getSExtValue();
    229       // Start with the LHS as an addr mode.
    230       if (!MatchAddress(N.getOperand(0), AM) &&
    231           // Address could not have picked a GV address for the displacement.
    232           AM.GV == nullptr &&
    233           // Check to see if the LHS & C is zero.
    234           CurDAG->MaskedValueIsZero(N.getOperand(0), CN->getAPIntValue())) {
    235         AM.Disp += Offset;
    236         return false;
    237       }
    238       AM = Backup;
    239     }
    240     break;
    241   }
    242 
    243   return MatchAddressBase(N, AM);
    244 }
    245 
    246 /// SelectAddr - returns true if it is able pattern match an addressing mode.
    247 /// It returns the operands which make up the maximal addressing mode it can
    248 /// match by reference.
    249 bool MSP430DAGToDAGISel::SelectAddr(SDValue N,
    250                                     SDValue &Base, SDValue &Disp) {
    251   MSP430ISelAddressMode AM;
    252 
    253   if (MatchAddress(N, AM))
    254     return false;
    255 
    256   EVT VT = N.getValueType();
    257   if (AM.BaseType == MSP430ISelAddressMode::RegBase) {
    258     if (!AM.Base.Reg.getNode())
    259       AM.Base.Reg = CurDAG->getRegister(0, VT);
    260   }
    261 
    262   Base  = (AM.BaseType == MSP430ISelAddressMode::FrameIndexBase) ?
    263     CurDAG->getTargetFrameIndex(AM.Base.FrameIndex,
    264                                 getTargetLowering()->getPointerTy()) :
    265     AM.Base.Reg;
    266 
    267   if (AM.GV)
    268     Disp = CurDAG->getTargetGlobalAddress(AM.GV, SDLoc(N),
    269                                           MVT::i16, AM.Disp,
    270                                           0/*AM.SymbolFlags*/);
    271   else if (AM.CP)
    272     Disp = CurDAG->getTargetConstantPool(AM.CP, MVT::i16,
    273                                          AM.Align, AM.Disp, 0/*AM.SymbolFlags*/);
    274   else if (AM.ES)
    275     Disp = CurDAG->getTargetExternalSymbol(AM.ES, MVT::i16, 0/*AM.SymbolFlags*/);
    276   else if (AM.JT != -1)
    277     Disp = CurDAG->getTargetJumpTable(AM.JT, MVT::i16, 0/*AM.SymbolFlags*/);
    278   else if (AM.BlockAddr)
    279     Disp = CurDAG->getTargetBlockAddress(AM.BlockAddr, MVT::i32, 0,
    280                                          0/*AM.SymbolFlags*/);
    281   else
    282     Disp = CurDAG->getTargetConstant(AM.Disp, MVT::i16);
    283 
    284   return true;
    285 }
    286 
    287 bool MSP430DAGToDAGISel::
    288 SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
    289                              std::vector<SDValue> &OutOps) {
    290   SDValue Op0, Op1;
    291   switch (ConstraintCode) {
    292   default: return true;
    293   case 'm':   // memory
    294     if (!SelectAddr(Op, Op0, Op1))
    295       return true;
    296     break;
    297   }
    298 
    299   OutOps.push_back(Op0);
    300   OutOps.push_back(Op1);
    301   return false;
    302 }
    303 
    304 static bool isValidIndexedLoad(const LoadSDNode *LD) {
    305   ISD::MemIndexedMode AM = LD->getAddressingMode();
    306   if (AM != ISD::POST_INC || LD->getExtensionType() != ISD::NON_EXTLOAD)
    307     return false;
    308 
    309   EVT VT = LD->getMemoryVT();
    310 
    311   switch (VT.getSimpleVT().SimpleTy) {
    312   case MVT::i8:
    313     // Sanity check
    314     if (cast<ConstantSDNode>(LD->getOffset())->getZExtValue() != 1)
    315       return false;
    316 
    317     break;
    318   case MVT::i16:
    319     // Sanity check
    320     if (cast<ConstantSDNode>(LD->getOffset())->getZExtValue() != 2)
    321       return false;
    322 
    323     break;
    324   default:
    325     return false;
    326   }
    327 
    328   return true;
    329 }
    330 
    331 SDNode *MSP430DAGToDAGISel::SelectIndexedLoad(SDNode *N) {
    332   LoadSDNode *LD = cast<LoadSDNode>(N);
    333   if (!isValidIndexedLoad(LD))
    334     return nullptr;
    335 
    336   MVT VT = LD->getMemoryVT().getSimpleVT();
    337 
    338   unsigned Opcode = 0;
    339   switch (VT.SimpleTy) {
    340   case MVT::i8:
    341     Opcode = MSP430::MOV8rm_POST;
    342     break;
    343   case MVT::i16:
    344     Opcode = MSP430::MOV16rm_POST;
    345     break;
    346   default:
    347     return nullptr;
    348   }
    349 
    350    return CurDAG->getMachineNode(Opcode, SDLoc(N),
    351                                  VT, MVT::i16, MVT::Other,
    352                                  LD->getBasePtr(), LD->getChain());
    353 }
    354 
    355 SDNode *MSP430DAGToDAGISel::SelectIndexedBinOp(SDNode *Op,
    356                                                SDValue N1, SDValue N2,
    357                                                unsigned Opc8, unsigned Opc16) {
    358   if (N1.getOpcode() == ISD::LOAD &&
    359       N1.hasOneUse() &&
    360       IsLegalToFold(N1, Op, Op, OptLevel)) {
    361     LoadSDNode *LD = cast<LoadSDNode>(N1);
    362     if (!isValidIndexedLoad(LD))
    363       return nullptr;
    364 
    365     MVT VT = LD->getMemoryVT().getSimpleVT();
    366     unsigned Opc = (VT == MVT::i16 ? Opc16 : Opc8);
    367     MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
    368     MemRefs0[0] = cast<MemSDNode>(N1)->getMemOperand();
    369     SDValue Ops0[] = { N2, LD->getBasePtr(), LD->getChain() };
    370     SDNode *ResNode =
    371       CurDAG->SelectNodeTo(Op, Opc, VT, MVT::i16, MVT::Other, Ops0);
    372     cast<MachineSDNode>(ResNode)->setMemRefs(MemRefs0, MemRefs0 + 1);
    373     // Transfer chain.
    374     ReplaceUses(SDValue(N1.getNode(), 2), SDValue(ResNode, 2));
    375     // Transfer writeback.
    376     ReplaceUses(SDValue(N1.getNode(), 1), SDValue(ResNode, 1));
    377     return ResNode;
    378   }
    379 
    380   return nullptr;
    381 }
    382 
    383 
    384 SDNode *MSP430DAGToDAGISel::Select(SDNode *Node) {
    385   SDLoc dl(Node);
    386 
    387   // Dump information about the Node being selected
    388   DEBUG(errs() << "Selecting: ");
    389   DEBUG(Node->dump(CurDAG));
    390   DEBUG(errs() << "\n");
    391 
    392   // If we have a custom node, we already have selected!
    393   if (Node->isMachineOpcode()) {
    394     DEBUG(errs() << "== ";
    395           Node->dump(CurDAG);
    396           errs() << "\n");
    397     Node->setNodeId(-1);
    398     return nullptr;
    399   }
    400 
    401   // Few custom selection stuff.
    402   switch (Node->getOpcode()) {
    403   default: break;
    404   case ISD::FrameIndex: {
    405     assert(Node->getValueType(0) == MVT::i16);
    406     int FI = cast<FrameIndexSDNode>(Node)->getIndex();
    407     SDValue TFI = CurDAG->getTargetFrameIndex(FI, MVT::i16);
    408     if (Node->hasOneUse())
    409       return CurDAG->SelectNodeTo(Node, MSP430::ADD16ri, MVT::i16,
    410                                   TFI, CurDAG->getTargetConstant(0, MVT::i16));
    411     return CurDAG->getMachineNode(MSP430::ADD16ri, dl, MVT::i16,
    412                                   TFI, CurDAG->getTargetConstant(0, MVT::i16));
    413   }
    414   case ISD::LOAD:
    415     if (SDNode *ResNode = SelectIndexedLoad(Node))
    416       return ResNode;
    417     // Other cases are autogenerated.
    418     break;
    419   case ISD::ADD:
    420     if (SDNode *ResNode =
    421         SelectIndexedBinOp(Node,
    422                            Node->getOperand(0), Node->getOperand(1),
    423                            MSP430::ADD8rm_POST, MSP430::ADD16rm_POST))
    424       return ResNode;
    425     else if (SDNode *ResNode =
    426              SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0),
    427                                 MSP430::ADD8rm_POST, MSP430::ADD16rm_POST))
    428       return ResNode;
    429 
    430     // Other cases are autogenerated.
    431     break;
    432   case ISD::SUB:
    433     if (SDNode *ResNode =
    434         SelectIndexedBinOp(Node,
    435                            Node->getOperand(0), Node->getOperand(1),
    436                            MSP430::SUB8rm_POST, MSP430::SUB16rm_POST))
    437       return ResNode;
    438 
    439     // Other cases are autogenerated.
    440     break;
    441   case ISD::AND:
    442     if (SDNode *ResNode =
    443         SelectIndexedBinOp(Node,
    444                            Node->getOperand(0), Node->getOperand(1),
    445                            MSP430::AND8rm_POST, MSP430::AND16rm_POST))
    446       return ResNode;
    447     else if (SDNode *ResNode =
    448              SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0),
    449                                 MSP430::AND8rm_POST, MSP430::AND16rm_POST))
    450       return ResNode;
    451 
    452     // Other cases are autogenerated.
    453     break;
    454   case ISD::OR:
    455     if (SDNode *ResNode =
    456         SelectIndexedBinOp(Node,
    457                            Node->getOperand(0), Node->getOperand(1),
    458                            MSP430::OR8rm_POST, MSP430::OR16rm_POST))
    459       return ResNode;
    460     else if (SDNode *ResNode =
    461              SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0),
    462                                 MSP430::OR8rm_POST, MSP430::OR16rm_POST))
    463       return ResNode;
    464 
    465     // Other cases are autogenerated.
    466     break;
    467   case ISD::XOR:
    468     if (SDNode *ResNode =
    469         SelectIndexedBinOp(Node,
    470                            Node->getOperand(0), Node->getOperand(1),
    471                            MSP430::XOR8rm_POST, MSP430::XOR16rm_POST))
    472       return ResNode;
    473     else if (SDNode *ResNode =
    474              SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0),
    475                                 MSP430::XOR8rm_POST, MSP430::XOR16rm_POST))
    476       return ResNode;
    477 
    478     // Other cases are autogenerated.
    479     break;
    480   }
    481 
    482   // Select the default instruction
    483   SDNode *ResNode = SelectCode(Node);
    484 
    485   DEBUG(errs() << "=> ");
    486   if (ResNode == nullptr || ResNode == Node)
    487     DEBUG(Node->dump(CurDAG));
    488   else
    489     DEBUG(ResNode->dump(CurDAG));
    490   DEBUG(errs() << "\n");
    491 
    492   return ResNode;
    493 }
    494