diff options
author | Sanjiv Gupta <sanjiv.gupta@microchip.com> | 2008-11-19 11:00:54 +0000 |
---|---|---|
committer | Sanjiv Gupta <sanjiv.gupta@microchip.com> | 2008-11-19 11:00:54 +0000 |
commit | 2ae21ee51798759d1fa455969f53c5a428e3f091 (patch) | |
tree | 5e5c4f32b0f5aa44036fd0c55e7da5c57184381b /llvm/lib/Target/PIC16/PIC16ISelDAGToDAG.cpp | |
parent | af7efa695c5c775dbe33a69c3b69c994a4fbaf2c (diff) | |
download | bcm5719-llvm-2ae21ee51798759d1fa455969f53c5a428e3f091.tar.gz bcm5719-llvm-2ae21ee51798759d1fa455969f53c5a428e3f091.zip |
Added a more function PIC16 backend. However to get this working a patch in
ExpandIntegerOperand (LegalizeIntegerTypes.cpp) is needed which is yet to be reworked and submitted.
llvm-svn: 59617
Diffstat (limited to 'llvm/lib/Target/PIC16/PIC16ISelDAGToDAG.cpp')
-rw-r--r-- | llvm/lib/Target/PIC16/PIC16ISelDAGToDAG.cpp | 260 |
1 files changed, 22 insertions, 238 deletions
diff --git a/llvm/lib/Target/PIC16/PIC16ISelDAGToDAG.cpp b/llvm/lib/Target/PIC16/PIC16ISelDAGToDAG.cpp index d98be99f86c..6c2b8ec9747 100644 --- a/llvm/lib/Target/PIC16/PIC16ISelDAGToDAG.cpp +++ b/llvm/lib/Target/PIC16/PIC16ISelDAGToDAG.cpp @@ -13,263 +13,47 @@ #define DEBUG_TYPE "pic16-isel" -#include "PIC16.h" -#include "PIC16ISelLowering.h" -#include "PIC16RegisterInfo.h" -#include "PIC16Subtarget.h" -#include "PIC16TargetMachine.h" -#include "llvm/GlobalValue.h" -#include "llvm/Instructions.h" -#include "llvm/Intrinsics.h" -#include "llvm/Type.h" -#include "llvm/CodeGen/MachineConstantPool.h" -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineFrameInfo.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/CodeGen/SelectionDAGISel.h" -#include "llvm/Support/CFG.h" -#include "llvm/Support/Compiler.h" +#include "PIC16ISelDAGToDAG.h" #include "llvm/Support/Debug.h" -#include "llvm/Target/TargetMachine.h" -using namespace llvm; - -//===----------------------------------------------------------------------===// -// Instruction Selector Implementation -//===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -// PIC16DAGToDAGISel - PIC16 specific code to select PIC16 machine -// instructions for SelectionDAG operations. -//===----------------------------------------------------------------------===// -namespace { - -class VISIBILITY_HIDDEN PIC16DAGToDAGISel : public SelectionDAGISel { - - /// TM - Keep a reference to PIC16TargetMachine. - PIC16TargetMachine &TM; -public: - explicit PIC16DAGToDAGISel(PIC16TargetMachine &tm) : - SelectionDAGISel(*tm.getTargetLowering()), - TM(tm) {} - - virtual void InstructionSelect(); - - // Pass Name - virtual const char *getPassName() const { - return "PIC16 DAG->DAG Pattern Instruction Selection"; - } - -private: - // Include the pieces autogenerated from the target description. -#include "PIC16GenDAGISel.inc" - - SDNode *Select(SDValue N); - - // Select addressing mode. currently assume base + offset addr mode. - bool SelectAM(SDValue Op, SDValue N, SDValue &Base, SDValue &Offset); - bool SelectDirectAM(SDValue Op, SDValue N, SDValue &Base, - SDValue &Offset); - bool StoreInDirectAM(SDValue Op, SDValue N, SDValue &fsr); - bool LoadFSR(SDValue Op, SDValue N, SDValue &Base, SDValue &Offset); - bool LoadNothing(SDValue Op, SDValue N, SDValue &Base, - SDValue &Offset); - - // getI8Imm - Return a target constant with the specified - // value, of type i8. - inline SDValue getI8Imm(unsigned Imm) { - return CurDAG->getTargetConstant(Imm, MVT::i8); - } - - -#ifndef NDEBUG - unsigned Indent; -#endif -}; +using namespace llvm; +/// createPIC16ISelDag - This pass converts a legalized DAG into a +/// PIC16-specific DAG, ready for instruction scheduling. +FunctionPass *llvm::createPIC16ISelDag(PIC16TargetMachine &TM) { + return new PIC16DAGToDAGISel(TM); } + /// InstructionSelect - This callback is invoked by /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. -void PIC16DAGToDAGISel::InstructionSelect() -{ +void PIC16DAGToDAGISel::InstructionSelect() { DEBUG(BB->dump()); - // Codegen the basic block. - - DOUT << "===== Instruction selection begins:\n"; -#ifndef NDEBUG - Indent = 0; -#endif - - // Select target instructions for the DAG. SelectRoot(*CurDAG); - - DOUT << "===== Instruction selection ends:\n"; - CurDAG->RemoveDeadNodes(); } - -bool PIC16DAGToDAGISel:: -SelectDirectAM (SDValue Op, SDValue N, SDValue &Base, SDValue &Offset) -{ - GlobalAddressSDNode *GA; - ConstantSDNode *GC; - - // if Address is FI, get the TargetFrameIndex. - if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(N)) { - DOUT << "--------- its frame Index\n"; - Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); - Offset = CurDAG->getTargetConstant(0, MVT::i32); - return true; - } - - if (N.getOpcode() == ISD::GlobalAddress) { - GA = dyn_cast<GlobalAddressSDNode>(N); - Offset = CurDAG->getTargetConstant((unsigned char)GA->getOffset(), MVT::i8); - Base = CurDAG->getTargetGlobalAddress(GA->getGlobal(), MVT::i16, - GA->getOffset()); - return true; - } - - if (N.getOpcode() == ISD::ADD) { - GC = dyn_cast<ConstantSDNode>(N.getOperand(1)); - Offset = CurDAG->getTargetConstant((unsigned char)GC->getZExtValue(), - MVT::i8); - if ((GA = dyn_cast<GlobalAddressSDNode>(N.getOperand(0)))) { - Base = CurDAG->getTargetGlobalAddress(GA->getGlobal(), MVT::i16, - GC->getZExtValue()); - return true; - } - else if (FrameIndexSDNode *FIN - = dyn_cast<FrameIndexSDNode>(N.getOperand(0))) { - Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); - return true; - } - } - - return false; -} - - -// FIXME: must also account for preinc/predec/postinc/postdec. -bool PIC16DAGToDAGISel:: -StoreInDirectAM (SDValue Op, SDValue N, SDValue &fsr) -{ - RegisterSDNode *Reg; - if (N.getOpcode() == ISD::LOAD) { - LoadSDNode *LD = dyn_cast<LoadSDNode>(N); - if (LD) { - fsr = LD->getBasePtr(); - } - else if (isa<RegisterSDNode>(N.getNode())) { - //FIXME an attempt to retrieve the register number - //but does not work - DOUT << "this is a register\n"; - Reg = dyn_cast<RegisterSDNode>(N.getNode()); - fsr = CurDAG->getRegister(Reg->getReg(),MVT::i16); - } - else { - DOUT << "this is not a register\n"; - // FIXME must use whatever load is using - fsr = CurDAG->getRegister(1,MVT::i16); - } - return true; - } - return false; -} - -bool PIC16DAGToDAGISel:: -LoadFSR (SDValue Op, SDValue N, SDValue &Base, SDValue &Offset) -{ - GlobalAddressSDNode *GA; - - if (N.getOpcode() == ISD::GlobalAddress) { - GA = dyn_cast<GlobalAddressSDNode>(N); - Offset = CurDAG->getTargetConstant((unsigned char)GA->getOffset(), MVT::i8); - Base = CurDAG->getTargetGlobalAddress(GA->getGlobal(), MVT::i16, - GA->getOffset()); - return true; - } - else if (N.getOpcode() == PIC16ISD::Package) { - CurDAG->setGraphColor(Op.getNode(), "blue"); - CurDAG->viewGraph(); - } - - return false; -} - -// LoadNothing - Don't thake this seriously, it will change. -bool PIC16DAGToDAGISel:: -LoadNothing (SDValue Op, SDValue N, SDValue &Base, SDValue &Offset) -{ - GlobalAddressSDNode *GA; - if (N.getOpcode() == ISD::GlobalAddress) { - GA = dyn_cast<GlobalAddressSDNode>(N); - DOUT << "==========" << GA->getOffset() << "\n"; - Offset = CurDAG->getTargetConstant((unsigned char)GA->getOffset(), MVT::i8); - Base = CurDAG->getTargetGlobalAddress(GA->getGlobal(), MVT::i16, - GA->getOffset()); - return true; - } - - return false; -} - - /// Select - Select instructions not customized! Used for /// expanded, promoted and normal instructions. -SDNode* PIC16DAGToDAGISel::Select(SDValue N) -{ - SDNode *Node = N.getNode(); - unsigned Opcode = Node->getOpcode(); - - // Dump information about the Node being selected -#ifndef NDEBUG - DOUT << std::string(Indent, ' ') << "Selecting: "; - DEBUG(Node->dump(CurDAG)); - DOUT << "\n"; - Indent += 2; -#endif - - // If we have a custom node, we already have selected! - if (Node->isMachineOpcode()) { -#ifndef NDEBUG - DOUT << std::string(Indent-2, ' ') << "== "; - DEBUG(Node->dump(CurDAG)); - DOUT << "\n"; - Indent -= 2; -#endif - return NULL; - } - - /// - // FIXME: Instruction Selection not handled by custom or by the - // auto-generated tablegen selection should be handled here. - /// - switch(Opcode) { - default: break; - } +SDNode* PIC16DAGToDAGISel::Select(SDValue N) { // Select the default instruction. SDNode *ResNode = SelectCode(N); -#ifndef NDEBUG - DOUT << std::string(Indent-2, ' ') << "=> "; - if (ResNode == NULL || ResNode == N.getNode()) - DEBUG(N.getNode()->dump(CurDAG)); - else - DEBUG(ResNode->dump(CurDAG)); - DOUT << "\n"; - Indent -= 2; -#endif - return ResNode; } -/// createPIC16ISelDag - This pass converts a legalized DAG into a -/// PIC16-specific DAG, ready for instruction scheduling. -FunctionPass *llvm::createPIC16ISelDag(PIC16TargetMachine &TM) { - return new PIC16DAGToDAGISel(TM); -} +// SelectDirectAddr - Match a direct address for DAG. +// A direct address could be a globaladdress or externalsymbol. +bool PIC16DAGToDAGISel::SelectDirectAddr(SDValue Op, SDValue N, + SDValue &Address) { + // Return true if TGA or ES. + if (N.getOpcode() == ISD::TargetGlobalAddress + || N.getOpcode() == ISD::TargetExternalSymbol) { + Address = N; + return true; + } + + return false; +} |