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...") |
|||
(2 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
− | The | + | The NaplesPUDAGToDAGISel class is used to transform target independent LLVM DAG nodes into platform dependent nodes. |
− | The class | + | |
− | * | + | <syntaxhighlight> |
+ | //===-- NaplesPUISelDAGToDAG.cpp - A dag to dag inst selector for NaplesPU ------===// | ||
+ | // | ||
+ | // 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 "naplespu-isel" | ||
+ | |||
+ | #include "NaplesPUTargetMachine.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 NaplesPUDAGToDAGISel : public SelectionDAGISel { | ||
+ | public: | ||
+ | explicit NaplesPUDAGToDAGISel(NaplesPUTargetMachine &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 "NaplesPU DAG->DAG Pattern Instruction Selection"; | ||
+ | } | ||
+ | |||
+ | #include "NaplesPUGenDAGISel.inc" | ||
+ | }; | ||
+ | } // end anonymous namespace | ||
+ | |||
+ | bool NaplesPUDAGToDAGISel::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 NaplesPUDAGToDAGISel::Select(SDNode *N) { | ||
+ | SDLoc DL(N); | ||
+ | if (N->isMachineOpcode()) | ||
+ | return; // Already selected. | ||
+ | |||
+ | SelectCode(N); | ||
+ | } | ||
+ | |||
+ | bool NaplesPUDAGToDAGISel::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::createNaplesPUISelDag(NaplesPUTargetMachine &TM) { | ||
+ | return new NaplesPUDAGToDAGISel(TM); | ||
+ | } | ||
+ | </syntaxhighlight> |
Latest revision as of 15:59, 21 June 2019
The NaplesPUDAGToDAGISel class is used to transform target independent LLVM DAG nodes into platform dependent nodes.
//===-- NaplesPUISelDAGToDAG.cpp - A dag to dag inst selector for NaplesPU ------===//
//
// 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 "naplespu-isel"
#include "NaplesPUTargetMachine.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 NaplesPUDAGToDAGISel : public SelectionDAGISel {
public:
explicit NaplesPUDAGToDAGISel(NaplesPUTargetMachine &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 "NaplesPU DAG->DAG Pattern Instruction Selection";
}
#include "NaplesPUGenDAGISel.inc"
};
} // end anonymous namespace
bool NaplesPUDAGToDAGISel::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 NaplesPUDAGToDAGISel::Select(SDNode *N) {
SDLoc DL(N);
if (N->isMachineOpcode())
return; // Already selected.
SelectCode(N);
}
bool NaplesPUDAGToDAGISel::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::createNaplesPUISelDag(NaplesPUTargetMachine &TM) {
return new NaplesPUDAGToDAGISel(TM);
}