Difference between revisions of "NaplesPUISelDAGToDAG.cpp"
From NaplesPU Documentation
(Created page with "The NuPlusDAGToDAGISel class is used to transform target independent LLVM DAG nodes into platform dependent nodes. The class implements the following methods: * The '''Select...") |
|||
Line 1: | Line 1: | ||
The NuPlusDAGToDAGISel class is used to transform target independent LLVM DAG nodes into platform dependent nodes. | The NuPlusDAGToDAGISel class is used to transform target independent LLVM DAG nodes into platform dependent nodes. | ||
− | The class | + | |
− | * | + | <syntaxhighlight> |
+ | //===-- NuPlusISelDAGToDAG.cpp - A dag to dag inst selector for NuPlus ------===// | ||
+ | // | ||
+ | // The LLVM Compiler Infrastructure | ||
+ | // | ||
+ | // This file is distributed under the University of Illinois Open Source | ||
+ | // License. See LICENSE.TXT for details. | ||
+ | // | ||
+ | //===----------------------------------------------------------------------===// | ||
+ | // | ||
+ | // This pass transforms target independent LLVM DAG nodes into platform | ||
+ | // dependent nodes that map, for the most part, directly to target instructions. | ||
+ | // | ||
+ | //===----------------------------------------------------------------------===// | ||
+ | |||
+ | #define DEBUG_TYPE "nuplus-isel" | ||
+ | |||
+ | #include "NuPlusTargetMachine.h" | ||
+ | #include "llvm/CodeGen/SelectionDAGISel.h" | ||
+ | #include "llvm/IR/Intrinsics.h" | ||
+ | #include "llvm/Support/Compiler.h" | ||
+ | #include "llvm/Support/Debug.h" | ||
+ | #include "llvm/Support/ErrorHandling.h" | ||
+ | #include "llvm/Support/raw_ostream.h" | ||
+ | using namespace llvm; | ||
+ | |||
+ | namespace { | ||
+ | class NuPlusDAGToDAGISel : public SelectionDAGISel { | ||
+ | public: | ||
+ | explicit NuPlusDAGToDAGISel(NuPlusTargetMachine &tm) : SelectionDAGISel(tm) {} | ||
+ | |||
+ | void Select(SDNode *N) override; | ||
+ | |||
+ | bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintCode, | ||
+ | std::vector<SDValue> &OutOps) override; | ||
+ | |||
+ | bool SelectADDRri(SDValue N, SDValue &Base, SDValue &Offset); | ||
+ | |||
+ | StringRef getPassName() const override { | ||
+ | return "NuPlus DAG->DAG Pattern Instruction Selection"; | ||
+ | } | ||
+ | |||
+ | #include "NuPlusGenDAGISel.inc" | ||
+ | }; | ||
+ | } // end anonymous namespace | ||
+ | |||
+ | bool NuPlusDAGToDAGISel::SelectADDRri(SDValue Addr, SDValue &Base, | ||
+ | SDValue &Offset) { | ||
+ | |||
+ | if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { | ||
+ | Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); | ||
+ | Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32); | ||
+ | return true; | ||
+ | } | ||
+ | |||
+ | if (Addr.getOpcode() == ISD::TargetExternalSymbol || | ||
+ | Addr.getOpcode() == ISD::TargetGlobalAddress) | ||
+ | return false; // direct calls. | ||
+ | |||
+ | if (Addr.getOpcode() == ISD::ADD) { | ||
+ | if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) { | ||
+ | if (isInt<9>(CN->getSExtValue())) { | ||
+ | if (FrameIndexSDNode *FIN = | ||
+ | dyn_cast<FrameIndexSDNode>(Addr.getOperand(0))) { | ||
+ | Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); | ||
+ | } else { | ||
+ | Base = Addr.getOperand(0); | ||
+ | } | ||
+ | Offset = CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Addr), | ||
+ | MVT::i32); | ||
+ | return true; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | Base = Addr; | ||
+ | Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32); | ||
+ | return true; | ||
+ | } | ||
+ | |||
+ | void NuPlusDAGToDAGISel::Select(SDNode *N) { | ||
+ | SDLoc DL(N); | ||
+ | if (N->isMachineOpcode()) | ||
+ | return; // Already selected. | ||
+ | |||
+ | SelectCode(N); | ||
+ | } | ||
+ | |||
+ | bool NuPlusDAGToDAGISel::SelectInlineAsmMemoryOperand( | ||
+ | const SDValue &Op, unsigned ConstraintCode, std::vector<SDValue> &OutOps) { | ||
+ | SDValue Op0, Op1; | ||
+ | switch (ConstraintCode) { | ||
+ | default: | ||
+ | return true; | ||
+ | |||
+ | case 'm': // memory | ||
+ | SelectADDRri(Op, Op0, Op1); | ||
+ | break; | ||
+ | |||
+ | } | ||
+ | |||
+ | OutOps.push_back(Op0); | ||
+ | OutOps.push_back(Op1); | ||
+ | return false; | ||
+ | } | ||
+ | |||
+ | FunctionPass *llvm::createNuPlusISelDag(NuPlusTargetMachine &TM) { | ||
+ | return new NuPlusDAGToDAGISel(TM); | ||
+ | } | ||
+ | </syntaxhighlight> |
Revision as of 13:11, 5 April 2019
The NuPlusDAGToDAGISel class is used to transform target independent LLVM DAG nodes into platform dependent nodes.
//===-- NuPlusISelDAGToDAG.cpp - A dag to dag inst selector for NuPlus ------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This pass transforms target independent LLVM DAG nodes into platform
// dependent nodes that map, for the most part, directly to target instructions.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "nuplus-isel"
#include "NuPlusTargetMachine.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
namespace {
class NuPlusDAGToDAGISel : public SelectionDAGISel {
public:
explicit NuPlusDAGToDAGISel(NuPlusTargetMachine &tm) : SelectionDAGISel(tm) {}
void Select(SDNode *N) override;
bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintCode,
std::vector<SDValue> &OutOps) override;
bool SelectADDRri(SDValue N, SDValue &Base, SDValue &Offset);
StringRef getPassName() const override {
return "NuPlus DAG->DAG Pattern Instruction Selection";
}
#include "NuPlusGenDAGISel.inc"
};
} // end anonymous namespace
bool NuPlusDAGToDAGISel::SelectADDRri(SDValue Addr, SDValue &Base,
SDValue &Offset) {
if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
return true;
}
if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
Addr.getOpcode() == ISD::TargetGlobalAddress)
return false; // direct calls.
if (Addr.getOpcode() == ISD::ADD) {
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
if (isInt<9>(CN->getSExtValue())) {
if (FrameIndexSDNode *FIN =
dyn_cast<FrameIndexSDNode>(Addr.getOperand(0))) {
Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
} else {
Base = Addr.getOperand(0);
}
Offset = CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Addr),
MVT::i32);
return true;
}
}
}
Base = Addr;
Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
return true;
}
void NuPlusDAGToDAGISel::Select(SDNode *N) {
SDLoc DL(N);
if (N->isMachineOpcode())
return; // Already selected.
SelectCode(N);
}
bool NuPlusDAGToDAGISel::SelectInlineAsmMemoryOperand(
const SDValue &Op, unsigned ConstraintCode, std::vector<SDValue> &OutOps) {
SDValue Op0, Op1;
switch (ConstraintCode) {
default:
return true;
case 'm': // memory
SelectADDRri(Op, Op0, Op1);
break;
}
OutOps.push_back(Op0);
OutOps.push_back(Op1);
return false;
}
FunctionPass *llvm::createNuPlusISelDag(NuPlusTargetMachine &TM) {
return new NuPlusDAGToDAGISel(TM);
}