XCoreISelDAGToDAG.cpp revision 207618
117651Speter//===-- XCoreISelDAGToDAG.cpp - A dag to dag inst selector for XCore ------===//
217651Speter//
317651Speter//                     The LLVM Compiler Infrastructure
417651Speter//
517651Speter// This file is distributed under the University of Illinois Open Source
617651Speter// License. See LICENSE.TXT for details.
717651Speter//
817651Speter//===----------------------------------------------------------------------===//
917651Speter//
1017651Speter// This file defines an instruction selector for the XCore target.
1117651Speter//
1217651Speter//===----------------------------------------------------------------------===//
1317651Speter
1417651Speter#include "XCore.h"
1517651Speter#include "XCoreTargetMachine.h"
1617651Speter#include "llvm/DerivedTypes.h"
1717651Speter#include "llvm/Function.h"
1817651Speter#include "llvm/Intrinsics.h"
1917651Speter#include "llvm/CallingConv.h"
2017651Speter#include "llvm/Constants.h"
2117651Speter#include "llvm/LLVMContext.h"
2217651Speter#include "llvm/CodeGen/MachineFrameInfo.h"
2317651Speter#include "llvm/CodeGen/MachineFunction.h"
2417651Speter#include "llvm/CodeGen/MachineInstrBuilder.h"
2517651Speter#include "llvm/CodeGen/MachineRegisterInfo.h"
2617651Speter#include "llvm/CodeGen/SelectionDAG.h"
2717651Speter#include "llvm/CodeGen/SelectionDAGISel.h"
2817651Speter#include "llvm/Target/TargetLowering.h"
2917651Speter#include "llvm/Support/Compiler.h"
3017651Speter#include "llvm/Support/Debug.h"
3117651Speter#include "llvm/Support/ErrorHandling.h"
3217651Speter#include "llvm/Support/raw_ostream.h"
3317651Speter#include <queue>
3417651Speter#include <set>
3517651Speterusing namespace llvm;
3617651Speter
3717651Speter/// XCoreDAGToDAGISel - XCore specific code to select XCore machine
3817651Speter/// instructions for SelectionDAG operations.
3917651Speter///
4017651Speternamespace {
4117651Speter  class XCoreDAGToDAGISel : public SelectionDAGISel {
4217651Speter    const XCoreTargetLowering &Lowering;
4317651Speter    const XCoreSubtarget &Subtarget;
4417651Speter
4517651Speter  public:
4617651Speter    XCoreDAGToDAGISel(XCoreTargetMachine &TM)
4717651Speter      : SelectionDAGISel(TM),
4817651Speter        Lowering(*TM.getTargetLowering()),
4917651Speter        Subtarget(*TM.getSubtargetImpl()) { }
5017651Speter
5117651Speter    SDNode *Select(SDNode *N);
5217651Speter
5317651Speter    /// getI32Imm - Return a target constant with the specified value, of type
5417651Speter    /// i32.
5517651Speter    inline SDValue getI32Imm(unsigned Imm) {
5617651Speter      return CurDAG->getTargetConstant(Imm, MVT::i32);
5717651Speter    }
5817651Speter
5917651Speter    // Complex Pattern Selectors.
6017651Speter    bool SelectADDRspii(SDNode *Op, SDValue Addr, SDValue &Base,
6117651Speter                        SDValue &Offset);
6217651Speter    bool SelectADDRdpii(SDNode *Op, SDValue Addr, SDValue &Base,
6317651Speter                        SDValue &Offset);
6417651Speter    bool SelectADDRcpii(SDNode *Op, SDValue Addr, SDValue &Base,
6517651Speter                        SDValue &Offset);
6617651Speter
6717651Speter    virtual const char *getPassName() const {
6817651Speter      return "XCore DAG->DAG Pattern Instruction Selection";
6917651Speter    }
7017651Speter
7117651Speter    // Include the pieces autogenerated from the target description.
7217651Speter  #include "XCoreGenDAGISel.inc"
7317651Speter  };
7417651Speter}  // end anonymous namespace
7517651Speter
7617651Speter/// createXCoreISelDag - This pass converts a legalized DAG into a
7717651Speter/// XCore-specific DAG, ready for instruction scheduling.
7817651Speter///
7917651SpeterFunctionPass *llvm::createXCoreISelDag(XCoreTargetMachine &TM) {
8017651Speter  return new XCoreDAGToDAGISel(TM);
8117651Speter}
8217651Speter
8317651Speterbool XCoreDAGToDAGISel::SelectADDRspii(SDNode *Op, SDValue Addr,
8417651Speter                                  SDValue &Base, SDValue &Offset) {
8517651Speter  FrameIndexSDNode *FIN = 0;
8617651Speter  if ((FIN = dyn_cast<FrameIndexSDNode>(Addr))) {
8717651Speter    Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
8817651Speter    Offset = CurDAG->getTargetConstant(0, MVT::i32);
8917651Speter    return true;
9017651Speter  }
9117651Speter  if (Addr.getOpcode() == ISD::ADD) {
9217651Speter    ConstantSDNode *CN = 0;
9317651Speter    if ((FIN = dyn_cast<FrameIndexSDNode>(Addr.getOperand(0)))
9417651Speter      && (CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
9517651Speter      && (CN->getSExtValue() % 4 == 0 && CN->getSExtValue() >= 0)) {
9617651Speter      // Constant positive word offset from frame index
9717651Speter      Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
9817651Speter      Offset = CurDAG->getTargetConstant(CN->getSExtValue(), MVT::i32);
9917651Speter      return true;
10017651Speter    }
10117651Speter  }
10217651Speter  return false;
10317651Speter}
10417651Speter
10517651Speterbool XCoreDAGToDAGISel::SelectADDRdpii(SDNode *Op, SDValue Addr,
10617651Speter                                  SDValue &Base, SDValue &Offset) {
10717651Speter  if (Addr.getOpcode() == XCoreISD::DPRelativeWrapper) {
10817651Speter    Base = Addr.getOperand(0);
10917651Speter    Offset = CurDAG->getTargetConstant(0, MVT::i32);
11017651Speter    return true;
11117651Speter  }
11217651Speter  if (Addr.getOpcode() == ISD::ADD) {
11317651Speter    ConstantSDNode *CN = 0;
11417651Speter    if ((Addr.getOperand(0).getOpcode() == XCoreISD::DPRelativeWrapper)
11517651Speter      && (CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
11617651Speter      && (CN->getSExtValue() % 4 == 0)) {
11717651Speter      // Constant word offset from a object in the data region
11817651Speter      Base = Addr.getOperand(0).getOperand(0);
11917651Speter      Offset = CurDAG->getTargetConstant(CN->getSExtValue(), MVT::i32);
12017651Speter      return true;
12117651Speter    }
12217651Speter  }
12317651Speter  return false;
12417651Speter}
12517651Speter
12617651Speterbool XCoreDAGToDAGISel::SelectADDRcpii(SDNode *Op, SDValue Addr,
12717651Speter                                  SDValue &Base, SDValue &Offset) {
12817651Speter  if (Addr.getOpcode() == XCoreISD::CPRelativeWrapper) {
12917651Speter    Base = Addr.getOperand(0);
13017651Speter    Offset = CurDAG->getTargetConstant(0, MVT::i32);
13117651Speter    return true;
13217651Speter  }
13317651Speter  if (Addr.getOpcode() == ISD::ADD) {
13417651Speter    ConstantSDNode *CN = 0;
13517651Speter    if ((Addr.getOperand(0).getOpcode() == XCoreISD::CPRelativeWrapper)
13617651Speter      && (CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
13717651Speter      && (CN->getSExtValue() % 4 == 0)) {
13817651Speter      // Constant word offset from a object in the data region
13917651Speter      Base = Addr.getOperand(0).getOperand(0);
14017651Speter      Offset = CurDAG->getTargetConstant(CN->getSExtValue(), MVT::i32);
14117651Speter      return true;
14217651Speter    }
14317651Speter  }
14417651Speter  return false;
14517651Speter}
14617651Speter
14717651SpeterSDNode *XCoreDAGToDAGISel::Select(SDNode *N) {
14817651Speter  DebugLoc dl = N->getDebugLoc();
14917651Speter  EVT NVT = N->getValueType(0);
15017651Speter  if (NVT == MVT::i32) {
15117651Speter    switch (N->getOpcode()) {
15217651Speter      default: break;
15317651Speter      case ISD::Constant: {
15417651Speter        if (Predicate_immMskBitp(N)) {
15517651Speter          // Transformation function: get the size of a mask
15617651Speter          int64_t MaskVal = cast<ConstantSDNode>(N)->getZExtValue();
15717651Speter          assert(isMask_32(MaskVal));
15817651Speter          // Look for the first non-zero bit
15917651Speter          SDValue MskSize = getI32Imm(32 - CountLeadingZeros_32(MaskVal));
16017651Speter          return CurDAG->getMachineNode(XCore::MKMSK_rus, dl,
16117651Speter                                        MVT::i32, MskSize);
16217651Speter        }
16317651Speter        else if (! Predicate_immU16(N)) {
16417651Speter          unsigned Val = cast<ConstantSDNode>(N)->getZExtValue();
16517651Speter          SDValue CPIdx =
16617651Speter            CurDAG->getTargetConstantPool(ConstantInt::get(
16717651Speter                                  Type::getInt32Ty(*CurDAG->getContext()), Val),
16817651Speter                                          TLI.getPointerTy());
16917651Speter          return CurDAG->getMachineNode(XCore::LDWCP_lru6, dl, MVT::i32,
17017651Speter                                        MVT::Other, CPIdx,
17117651Speter                                        CurDAG->getEntryNode());
17217651Speter        }
17317651Speter        break;
17417651Speter      }
17517651Speter      case XCoreISD::LADD: {
17617651Speter        SDValue Ops[] = { N->getOperand(0), N->getOperand(1),
17717651Speter                            N->getOperand(2) };
17817651Speter        return CurDAG->getMachineNode(XCore::LADD_l5r, dl, MVT::i32, MVT::i32,
17917651Speter                                      Ops, 3);
18017651Speter      }
18117651Speter      case XCoreISD::LSUB: {
18217651Speter        SDValue Ops[] = { N->getOperand(0), N->getOperand(1),
18317651Speter                            N->getOperand(2) };
18417651Speter        return CurDAG->getMachineNode(XCore::LSUB_l5r, dl, MVT::i32, MVT::i32,
18517651Speter                                      Ops, 3);
18617651Speter      }
18717651Speter      case XCoreISD::MACCU: {
18817651Speter        SDValue Ops[] = { N->getOperand(0), N->getOperand(1),
18917651Speter                          N->getOperand(2), N->getOperand(3) };
19017651Speter        return CurDAG->getMachineNode(XCore::MACCU_l4r, dl, MVT::i32, MVT::i32,
19117651Speter                                      Ops, 4);
19217651Speter      }
19317651Speter      case XCoreISD::MACCS: {
19417651Speter        SDValue Ops[] = { N->getOperand(0), N->getOperand(1),
19517651Speter                          N->getOperand(2), N->getOperand(3) };
19617651Speter        return CurDAG->getMachineNode(XCore::MACCS_l4r, dl, MVT::i32, MVT::i32,
19717651Speter                                      Ops, 4);
19817651Speter      }
19917651Speter      case XCoreISD::LMUL: {
20017651Speter        SDValue Ops[] = { N->getOperand(0), N->getOperand(1),
20117651Speter                          N->getOperand(2), N->getOperand(3) };
20217651Speter        return CurDAG->getMachineNode(XCore::LMUL_l6r, dl, MVT::i32, MVT::i32,
20317651Speter                                      Ops, 4);
20417651Speter      }
20517651Speter      // Other cases are autogenerated.
20617651Speter    }
20717651Speter  }
20817651Speter  return SelectCode(N);
20917651Speter}
21017651Speter