mirror of
https://github.com/Gericom/teak-llvm.git
synced 2025-06-18 19:15:51 -04:00
199 lines
6.5 KiB
C++
199 lines
6.5 KiB
C++
//===-- TeakISelDAGToDAG.cpp - A dag to dag inst selector for Teak ------===//
|
|
//
|
|
// 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 Teak target.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "Teak.h"
|
|
#include "TeakTargetMachine.h"
|
|
#include "llvm/CodeGen/SelectionDAGISel.h"
|
|
#include "llvm/Support/Compiler.h"
|
|
#include "llvm/Support/Debug.h"
|
|
#include "llvm/Support/ErrorHandling.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
|
|
#include "TeakInstrInfo.h"
|
|
|
|
using namespace llvm;
|
|
|
|
/// TeakDAGToDAGISel - Teak specific code to select Teak machine
|
|
/// instructions for SelectionDAG operations.
|
|
///
|
|
namespace
|
|
{
|
|
class TeakDAGToDAGISel : public SelectionDAGISel
|
|
{
|
|
const TeakSubtarget &Subtarget;
|
|
|
|
public:
|
|
explicit TeakDAGToDAGISel(TeakTargetMachine &TM, CodeGenOpt::Level OptLevel)
|
|
: SelectionDAGISel(TM, OptLevel), Subtarget(*TM.getSubtargetImpl()) {}
|
|
|
|
void Select(SDNode *N) override;
|
|
|
|
bool SelectAddr(SDValue Addr, SDValue &Base, SDValue &Offset);
|
|
|
|
virtual StringRef getPassName() const override
|
|
{
|
|
return "Teak DAG->DAG Pattern Instruction Selection";
|
|
}
|
|
|
|
private:
|
|
// SDNode *SelectMoveImmediate(SDNode *N);
|
|
// SDNode *SelectConditionalBranch(SDNode *N);
|
|
bool SelectLoad(SDNode* N);
|
|
//bool SelectBRICC(SDNode* node);
|
|
|
|
// Include the pieces autogenerated from the target description.
|
|
#include "TeakGenDAGISel.inc"
|
|
};
|
|
} // end anonymous namespace
|
|
|
|
bool TeakDAGToDAGISel::SelectAddr(SDValue Addr, SDValue &Base, SDValue& Offset)
|
|
{
|
|
dbgs() << "TeakDAGToDAGISel::SelectAddr: " << Addr.getOpcode() << "\n";
|
|
if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr))
|
|
{
|
|
EVT PtrVT = getTargetLowering()->getPointerTy(CurDAG->getDataLayout());
|
|
Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), PtrVT);
|
|
Offset = CurDAG->getTargetConstant(0, Addr, MVT::i16);
|
|
return true;
|
|
}
|
|
return false;
|
|
// if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
|
|
// Addr.getOpcode() == ISD::TargetGlobalAddress ||
|
|
// Addr.getOpcode() == ISD::TargetGlobalTLSAddress)
|
|
// {
|
|
// return false; // direct calls.
|
|
// }
|
|
|
|
// Base = Addr;
|
|
// Offset = CurDAG->getTargetConstant(0, Addr, MVT::i16);
|
|
// return true;
|
|
}
|
|
|
|
// SDNode *TeakDAGToDAGISel::SelectMoveImmediate(SDNode *N) {
|
|
// // Make sure the immediate size is supported.
|
|
// ConstantSDNode *ConstVal = cast<ConstantSDNode>(N);
|
|
// uint64_t ImmVal = ConstVal->getZExtValue();
|
|
// uint64_t SupportedMask = 0xfffffffff;
|
|
// if ((ImmVal & SupportedMask) != ImmVal) {
|
|
// return SelectCode(N);
|
|
// }
|
|
|
|
// // Select the low part of the immediate move.
|
|
// uint64_t LoMask = 0xffff;
|
|
// uint64_t HiMask = 0xffff0000;
|
|
// uint64_t ImmLo = (ImmVal & LoMask);
|
|
// uint64_t ImmHi = (ImmVal & HiMask);
|
|
// SDValue ConstLo = CurDAG->getTargetConstant(ImmLo, N, MVT::i32);
|
|
// MachineSDNode *Move =
|
|
// CurDAG->getMachineNode(Teak::MOVLOi16, N, MVT::i32, ConstLo);
|
|
|
|
// // Select the low part of the immediate move, if needed.
|
|
// if (ImmHi) {
|
|
// SDValue ConstHi = CurDAG->getTargetConstant(ImmHi >> 16, N, MVT::i32);
|
|
// Move = CurDAG->getMachineNode(Teak::MOVHIi16, N, MVT::i32, SDValue(Move,
|
|
// 0),
|
|
// ConstHi);
|
|
// }
|
|
|
|
// return Move;
|
|
// }
|
|
|
|
// SDNode *TeakDAGToDAGISel::SelectConditionalBranch(SDNode *N) {
|
|
// SDValue Chain = N->getOperand(0);
|
|
// SDValue Cond = N->getOperand(1);
|
|
// SDValue LHS = N->getOperand(2);
|
|
// SDValue RHS = N->getOperand(3);
|
|
// SDValue Target = N->getOperand(4);
|
|
|
|
// // Generate a comparison instruction.
|
|
// EVT CompareTys[] = { MVT::Other, MVT::Glue };
|
|
// SDVTList CompareVT = CurDAG->getVTList(CompareTys);
|
|
// SDValue CompareOps[] = {LHS, RHS, Chain};
|
|
// SDNode *Compare = CurDAG->getMachineNode(Teak::CMP, N, CompareVT,
|
|
// CompareOps);
|
|
|
|
// // Generate a predicated branch instruction.
|
|
// CondCodeSDNode *CC = cast<CondCodeSDNode>(Cond.getNode());
|
|
// SDValue CCVal = CurDAG->getTargetConstant(CC->get(), N, MVT::i32);
|
|
// SDValue BranchOps[] = {CCVal, Target, SDValue(Compare, 0),
|
|
// SDValue(Compare, 1)};
|
|
// return CurDAG->getMachineNode(Teak::Bcc, N, MVT::Other, BranchOps);
|
|
// }
|
|
|
|
bool TeakDAGToDAGISel::SelectLoad(SDNode* node)
|
|
{
|
|
dbgs() << "TeakDAGToDAGISel::SelectLoad\n";
|
|
const LoadSDNode* ld = cast<LoadSDNode>(node);
|
|
ISD::MemIndexedMode idxMode = ld->getAddressingMode();
|
|
MVT vType = ld->getMemoryVT().getSimpleVT();
|
|
//ld->dump();
|
|
dbgs() << "mode: " << idxMode << "\n";
|
|
if(idxMode != ISD::POST_INC && idxMode != ISD::POST_DEC)
|
|
return false;
|
|
int offs = cast<ConstantSDNode>(ld->getOffset())->getSExtValue();
|
|
dbgs() << "offset: " << offs << "\n";
|
|
return false;
|
|
}
|
|
|
|
// bool TeakDAGToDAGISel::SelectBRICC(SDNode* node)
|
|
// {
|
|
// SDValue dst = node->getOperand(0);
|
|
// SDValue cond = node->getOperand(1);
|
|
// SDValue shit = node->getOperand(2);
|
|
// SDValue branchOps[] = { dst, cond, CurDAG->getRegister(Teak::ICC, MVT::i32), shit };
|
|
// SDNode* resNode = CurDAG->getMachineNode(Teak::BRR_rel7, node, MVT::Other, branchOps);
|
|
// ReplaceUses(SDValue(node, 0), SDValue(resNode, 0));
|
|
// CurDAG->RemoveDeadNode(node);
|
|
// return true;
|
|
// }
|
|
|
|
void TeakDAGToDAGISel::Select(SDNode* N)
|
|
{
|
|
switch (N->getOpcode())
|
|
{
|
|
case ISD::LOAD:
|
|
if(SelectLoad(N))
|
|
return;
|
|
break;
|
|
// case TeakISD::BRICC:
|
|
// if(SelectBRICC(N))
|
|
// return;
|
|
// break;
|
|
}
|
|
|
|
// if (N->isMachineOpcode()) {
|
|
// N->setNodeId(-1);
|
|
// return; // Already selected.
|
|
// }
|
|
// if(N->getOpcode() == TeakISD::RET_FLAG)
|
|
// {
|
|
// SelectCode(N);
|
|
// return;
|
|
// }
|
|
// else if(N->getOpcode() == ISD::FrameIndex)
|
|
// {
|
|
|
|
// }
|
|
// N->dump();
|
|
// dbgs() << "opcode: " << N->getOpcode() << "\n";
|
|
//llvm_unreachable("Unimplemented TeakDAGToDAGISel::Select");
|
|
SelectCode(N);
|
|
}
|
|
|
|
/// createTeakISelDag - This pass converts a legalized DAG into a
|
|
/// Teak-specific DAG, ready for instruction scheduling.
|
|
///
|
|
FunctionPass *llvm::createTeakISelDag(TeakTargetMachine &TM, CodeGenOpt::Level OptLevel)
|
|
{
|
|
return new TeakDAGToDAGISel(TM, OptLevel);
|
|
} |