Index: lib/Target/NDS32/CMakeLists.txt =================================================================== --- lib/Target/NDS32/CMakeLists.txt +++ lib/Target/NDS32/CMakeLists.txt @@ -3,6 +3,7 @@ tablegen(LLVM NDS32GenSubtargetInfo.inc -gen-subtarget) tablegen(LLVM NDS32GenRegisterInfo.inc -gen-register-info) tablegen(LLVM NDS32GenInstrInfo.inc -gen-instr-info) +tablegen(LLVM NDS32GenDAGISel.inc -gen-dag-isel) add_public_tablegen_target(NDS32CommonTableGen) @@ -13,6 +14,7 @@ NDS32FrameLowering.cpp NDS32RegisterInfo.cpp NDS32InstrInfo.cpp + NDS32ISelDAGToDAG.cpp ) add_subdirectory(TargetInfo) Index: lib/Target/NDS32/NDS32.h =================================================================== --- lib/Target/NDS32/NDS32.h +++ lib/Target/NDS32/NDS32.h @@ -22,6 +22,8 @@ class NDS32TargetMachine; class FunctionPass; + FunctionPass *createNDS32ISelDag(NDS32TargetMachine &TM, + CodeGenOpt::Level OptLevel); } // end namespace llvm; #endif Index: lib/Target/NDS32/NDS32ISelDAGToDAG.cpp =================================================================== --- /dev/null +++ lib/Target/NDS32/NDS32ISelDAGToDAG.cpp @@ -0,0 +1,136 @@ +//===-- NDS32ISelDAGToDAG.cpp - A dag to dag inst selector for NDS32 ------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines an instruction selector for the NDS32 target. +// +//===----------------------------------------------------------------------===// + +#include "NDS32.h" +#include "NDS32TargetMachine.h" +#include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/SelectionDAG.h" +#include "llvm/CodeGen/SelectionDAGISel.h" +#include "llvm/IR/CallingConv.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/Intrinsics.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Target/TargetLowering.h" +using namespace llvm; + +#define DEBUG_TYPE "NDS32-isel" + +/// NDS32DAGToDAGISel - NDS32 specific code to select NDS32 machine +/// instructions for SelectionDAG operations. +/// +namespace { + class NDS32DAGToDAGISel : public SelectionDAGISel { + /// Subtarget - Keep a pointer to the NDS32Subtarget around so that we can + /// make the right decision when generating code for different targets. + const NDS32Subtarget *Subtarget; + + public: + NDS32DAGToDAGISel(NDS32TargetMachine &TM, CodeGenOpt::Level OptLevel) + : SelectionDAGISel(TM, OptLevel) {} + + bool runOnMachineFunction(MachineFunction &MF) override { + // Reset the subtarget each time through. + Subtarget = &MF.getSubtarget(); + SelectionDAGISel::runOnMachineFunction(MF); + return true; + } + + // Pass Name + StringRef getPassName() const override { + return "NDS32 DAG->DAG Pattern Instruction Selection"; + } + + bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID, + std::vector &OutOps) override; + + // Include the pieces autogenerated from the target description. + #include "NDS32GenDAGISel.inc" + + private: + void Select(SDNode *N) override; + + // getImm - Return a target constant with the specified value. + inline SDValue getImm(const SDNode *Node, uint64_t Imm) { + return CurDAG->getTargetConstant(Imm, SDLoc(Node), Node->getValueType(0)); + } + }; +} // end anonymous namespace + +/// createNDS32ISelDag - This pass converts a legalized DAG into a +/// NDS32-specific DAG, ready for instruction scheduling. +/// +FunctionPass *llvm::createNDS32ISelDag(NDS32TargetMachine &TM, + CodeGenOpt::Level OptLevel) { + return new NDS32DAGToDAGISel(TM, OptLevel); +} + +bool NDS32DAGToDAGISel:: +SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID, + std::vector &OutOps) { + return true; +} + +void NDS32DAGToDAGISel::Select(SDNode *Node) { + SDLoc dl(Node); + + // Dump information about the Node being selected + DEBUG(errs() << "Selecting: "); + DEBUG(Node->dump(CurDAG)); + DEBUG(errs() << "\n"); + + // If we have a custom node, we already have selected! + if (Node->isMachineOpcode()) { + DEBUG(errs() << "== "; + Node->dump(CurDAG); + errs() << "\n"); + Node->setNodeId(-1); + return; + } + + // Few custom selection stuff. + switch (Node->getOpcode()) { + default: break; + case ISD::FrameIndex: { + break; + } + case ISD::LOAD: + break; + case ISD::STORE: + break; + case ISD::ADD: + // Other cases are autogenerated. + break; + case ISD::SUB: + // Other cases are autogenerated. + break; + case ISD::AND: + // Other cases are autogenerated. + break; + case ISD::OR: + // Other cases are autogenerated. + break; + case ISD::XOR: + // Other cases are autogenerated. + break; + } + + // Select the default instruction + SelectCode(Node); +} Index: lib/Target/NDS32/NDS32TargetMachine.cpp =================================================================== --- lib/Target/NDS32/NDS32TargetMachine.cpp +++ lib/Target/NDS32/NDS32TargetMachine.cpp @@ -116,9 +116,16 @@ NDS32TargetMachine &getNDS32TargetMachine() const { return getTM(); } + bool addInstSelector() override; }; } // namespace TargetPassConfig *NDS32TargetMachine::createPassConfig(PassManagerBase &PM) { return new NDS32PassConfig(this, PM); } + +bool NDS32PassConfig::addInstSelector() { + // Install an instruction selector. + addPass(createNDS32ISelDag(getNDS32TargetMachine(), getOptLevel())); + return false; +}