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