Home | History | Annotate | Download | only in Mips
      1 //===-- MipsISelDAGToDAG.cpp - A Dag to Dag Inst Selector for Mips --------===//
      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 MIPS target.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "MipsISelDAGToDAG.h"
     15 #include "MCTargetDesc/MipsBaseInfo.h"
     16 #include "Mips.h"
     17 #include "Mips16ISelDAGToDAG.h"
     18 #include "MipsMachineFunction.h"
     19 #include "MipsRegisterInfo.h"
     20 #include "MipsSEISelDAGToDAG.h"
     21 #include "llvm/CodeGen/MachineConstantPool.h"
     22 #include "llvm/CodeGen/MachineFrameInfo.h"
     23 #include "llvm/CodeGen/MachineFunction.h"
     24 #include "llvm/CodeGen/MachineInstrBuilder.h"
     25 #include "llvm/CodeGen/MachineRegisterInfo.h"
     26 #include "llvm/CodeGen/SelectionDAGNodes.h"
     27 #include "llvm/IR/CFG.h"
     28 #include "llvm/IR/GlobalValue.h"
     29 #include "llvm/IR/Instructions.h"
     30 #include "llvm/IR/Intrinsics.h"
     31 #include "llvm/IR/Type.h"
     32 #include "llvm/Support/Debug.h"
     33 #include "llvm/Support/ErrorHandling.h"
     34 #include "llvm/Support/raw_ostream.h"
     35 #include "llvm/Target/TargetMachine.h"
     36 using namespace llvm;
     37 
     38 #define DEBUG_TYPE "mips-isel"
     39 
     40 //===----------------------------------------------------------------------===//
     41 // Instruction Selector Implementation
     42 //===----------------------------------------------------------------------===//
     43 
     44 //===----------------------------------------------------------------------===//
     45 // MipsDAGToDAGISel - MIPS specific code to select MIPS machine
     46 // instructions for SelectionDAG operations.
     47 //===----------------------------------------------------------------------===//
     48 
     49 bool MipsDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) {
     50   Subtarget = &static_cast<const MipsSubtarget &>(MF.getSubtarget());
     51   bool Ret = SelectionDAGISel::runOnMachineFunction(MF);
     52 
     53   processFunctionAfterISel(MF);
     54 
     55   return Ret;
     56 }
     57 
     58 /// getGlobalBaseReg - Output the instructions required to put the
     59 /// GOT address into a register.
     60 SDNode *MipsDAGToDAGISel::getGlobalBaseReg() {
     61   unsigned GlobalBaseReg = MF->getInfo<MipsFunctionInfo>()->getGlobalBaseReg();
     62   return CurDAG->getRegister(GlobalBaseReg, getTargetLowering()->getPointerTy(
     63                                                 CurDAG->getDataLayout()))
     64       .getNode();
     65 }
     66 
     67 /// ComplexPattern used on MipsInstrInfo
     68 /// Used on Mips Load/Store instructions
     69 bool MipsDAGToDAGISel::selectAddrRegImm(SDValue Addr, SDValue &Base,
     70                                         SDValue &Offset) const {
     71   llvm_unreachable("Unimplemented function.");
     72   return false;
     73 }
     74 
     75 bool MipsDAGToDAGISel::selectAddrRegReg(SDValue Addr, SDValue &Base,
     76                                         SDValue &Offset) const {
     77   llvm_unreachable("Unimplemented function.");
     78   return false;
     79 }
     80 
     81 bool MipsDAGToDAGISel::selectAddrDefault(SDValue Addr, SDValue &Base,
     82                                          SDValue &Offset) const {
     83   llvm_unreachable("Unimplemented function.");
     84   return false;
     85 }
     86 
     87 bool MipsDAGToDAGISel::selectIntAddr(SDValue Addr, SDValue &Base,
     88                                      SDValue &Offset) const {
     89   llvm_unreachable("Unimplemented function.");
     90   return false;
     91 }
     92 
     93 bool MipsDAGToDAGISel::selectIntAddrMM(SDValue Addr, SDValue &Base,
     94                                        SDValue &Offset) const {
     95   llvm_unreachable("Unimplemented function.");
     96   return false;
     97 }
     98 
     99 bool MipsDAGToDAGISel::selectIntAddrLSL2MM(SDValue Addr, SDValue &Base,
    100                                            SDValue &Offset) const {
    101   llvm_unreachable("Unimplemented function.");
    102   return false;
    103 }
    104 
    105 bool MipsDAGToDAGISel::selectIntAddrMSA(SDValue Addr, SDValue &Base,
    106                                         SDValue &Offset) const {
    107   llvm_unreachable("Unimplemented function.");
    108   return false;
    109 }
    110 
    111 bool MipsDAGToDAGISel::selectAddr16(SDNode *Parent, SDValue N, SDValue &Base,
    112                                     SDValue &Offset, SDValue &Alias) {
    113   llvm_unreachable("Unimplemented function.");
    114   return false;
    115 }
    116 
    117 bool MipsDAGToDAGISel::selectVSplat(SDNode *N, APInt &Imm,
    118                                     unsigned MinSizeInBits) const {
    119   llvm_unreachable("Unimplemented function.");
    120   return false;
    121 }
    122 
    123 bool MipsDAGToDAGISel::selectVSplatUimm1(SDValue N, SDValue &Imm) const {
    124   llvm_unreachable("Unimplemented function.");
    125   return false;
    126 }
    127 
    128 bool MipsDAGToDAGISel::selectVSplatUimm2(SDValue N, SDValue &Imm) const {
    129   llvm_unreachable("Unimplemented function.");
    130   return false;
    131 }
    132 
    133 bool MipsDAGToDAGISel::selectVSplatUimm3(SDValue N, SDValue &Imm) const {
    134   llvm_unreachable("Unimplemented function.");
    135   return false;
    136 }
    137 
    138 bool MipsDAGToDAGISel::selectVSplatUimm4(SDValue N, SDValue &Imm) const {
    139   llvm_unreachable("Unimplemented function.");
    140   return false;
    141 }
    142 
    143 bool MipsDAGToDAGISel::selectVSplatUimm5(SDValue N, SDValue &Imm) const {
    144   llvm_unreachable("Unimplemented function.");
    145   return false;
    146 }
    147 
    148 bool MipsDAGToDAGISel::selectVSplatUimm6(SDValue N, SDValue &Imm) const {
    149   llvm_unreachable("Unimplemented function.");
    150   return false;
    151 }
    152 
    153 bool MipsDAGToDAGISel::selectVSplatUimm8(SDValue N, SDValue &Imm) const {
    154   llvm_unreachable("Unimplemented function.");
    155   return false;
    156 }
    157 
    158 bool MipsDAGToDAGISel::selectVSplatSimm5(SDValue N, SDValue &Imm) const {
    159   llvm_unreachable("Unimplemented function.");
    160   return false;
    161 }
    162 
    163 bool MipsDAGToDAGISel::selectVSplatUimmPow2(SDValue N, SDValue &Imm) const {
    164   llvm_unreachable("Unimplemented function.");
    165   return false;
    166 }
    167 
    168 bool MipsDAGToDAGISel::selectVSplatUimmInvPow2(SDValue N, SDValue &Imm) const {
    169   llvm_unreachable("Unimplemented function.");
    170   return false;
    171 }
    172 
    173 bool MipsDAGToDAGISel::selectVSplatMaskL(SDValue N, SDValue &Imm) const {
    174   llvm_unreachable("Unimplemented function.");
    175   return false;
    176 }
    177 
    178 bool MipsDAGToDAGISel::selectVSplatMaskR(SDValue N, SDValue &Imm) const {
    179   llvm_unreachable("Unimplemented function.");
    180   return false;
    181 }
    182 
    183 /// Select instructions not customized! Used for
    184 /// expanded, promoted and normal instructions
    185 SDNode* MipsDAGToDAGISel::Select(SDNode *Node) {
    186   unsigned Opcode = Node->getOpcode();
    187 
    188   // Dump information about the Node being selected
    189   DEBUG(errs() << "Selecting: "; Node->dump(CurDAG); errs() << "\n");
    190 
    191   // If we have a custom node, we already have selected!
    192   if (Node->isMachineOpcode()) {
    193     DEBUG(errs() << "== "; Node->dump(CurDAG); errs() << "\n");
    194     Node->setNodeId(-1);
    195     return nullptr;
    196   }
    197 
    198   // See if subclasses can handle this node.
    199   std::pair<bool, SDNode*> Ret = selectNode(Node);
    200 
    201   if (Ret.first)
    202     return Ret.second;
    203 
    204   switch(Opcode) {
    205   default: break;
    206 
    207   // Get target GOT address.
    208   case ISD::GLOBAL_OFFSET_TABLE:
    209     return getGlobalBaseReg();
    210 
    211 #ifndef NDEBUG
    212   case ISD::LOAD:
    213   case ISD::STORE:
    214     assert((Subtarget->systemSupportsUnalignedAccess() ||
    215             cast<MemSDNode>(Node)->getMemoryVT().getSizeInBits() / 8 <=
    216             cast<MemSDNode>(Node)->getAlignment()) &&
    217            "Unexpected unaligned loads/stores.");
    218     break;
    219 #endif
    220   }
    221 
    222   // Select the default instruction
    223   SDNode *ResNode = SelectCode(Node);
    224 
    225   DEBUG(errs() << "=> ");
    226   if (ResNode == nullptr || ResNode == Node)
    227     DEBUG(Node->dump(CurDAG));
    228   else
    229     DEBUG(ResNode->dump(CurDAG));
    230   DEBUG(errs() << "\n");
    231   return ResNode;
    232 }
    233 
    234 bool MipsDAGToDAGISel::
    235 SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID,
    236                              std::vector<SDValue> &OutOps) {
    237   // All memory constraints can at least accept raw pointers.
    238   switch(ConstraintID) {
    239   default:
    240     llvm_unreachable("Unexpected asm memory constraint");
    241   case InlineAsm::Constraint_i:
    242   case InlineAsm::Constraint_m:
    243   case InlineAsm::Constraint_R:
    244   case InlineAsm::Constraint_ZC:
    245     OutOps.push_back(Op);
    246     return false;
    247   }
    248   return true;
    249 }
    250