1894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===- BlackfinISelDAGToDAG.cpp - A dag to dag inst selector for Blackfin -===// 2894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 3894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// The LLVM Compiler Infrastructure 4894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 5894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file is distributed under the University of Illinois Open Source 6894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// License. See LICENSE.TXT for details. 7894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 8894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 9894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 10894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file defines an instruction selector for the Blackfin target. 11894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 12894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 13894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 14894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "Blackfin.h" 15894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "BlackfinTargetMachine.h" 16894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "BlackfinRegisterInfo.h" 17894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Intrinsics.h" 18894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/SelectionDAGISel.h" 19894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineRegisterInfo.h" 20894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/Compiler.h" 21894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/Debug.h" 22894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/ErrorHandling.h" 23894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/raw_ostream.h" 24894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 25894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanusing namespace llvm; 26894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 27894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 28894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Instruction Selector Implementation 29894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 30894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 31894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 32894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// BlackfinDAGToDAGISel - Blackfin specific code to select blackfin machine 33894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// instructions for SelectionDAG operations. 34894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumannamespace { 35894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman class BlackfinDAGToDAGISel : public SelectionDAGISel { 36894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// Subtarget - Keep a pointer to the Blackfin Subtarget around so that we 37894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// can make the right decision when generating code for different targets. 38894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman //const BlackfinSubtarget &Subtarget; 39894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman public: 40894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BlackfinDAGToDAGISel(BlackfinTargetMachine &TM, CodeGenOpt::Level OptLevel) 41894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman : SelectionDAGISel(TM, OptLevel) {} 42894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 43894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman virtual void PostprocessISelDAG(); 44894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 45894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman virtual const char *getPassName() const { 46894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return "Blackfin DAG->DAG Pattern Instruction Selection"; 47894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 48894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 49894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Include the pieces autogenerated from the target description. 50894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "BlackfinGenDAGISel.inc" 51894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 52894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman private: 53894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *Select(SDNode *N); 5419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool SelectADDRspii(SDValue Addr, SDValue &Base, SDValue &Offset); 55894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 56894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Walk the DAG after instruction selection, fixing register class issues. 57894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void FixRegisterClasses(SelectionDAG &DAG); 58894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 59894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const BlackfinInstrInfo &getInstrInfo() { 60894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return *static_cast<const BlackfinTargetMachine&>(TM).getInstrInfo(); 61894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 62894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const BlackfinRegisterInfo *getRegisterInfo() { 63894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return static_cast<const BlackfinTargetMachine&>(TM).getRegisterInfo(); 64894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 65894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman }; 66894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} // end anonymous namespace 67894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 68894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanFunctionPass *llvm::createBlackfinISelDag(BlackfinTargetMachine &TM, 69894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CodeGenOpt::Level OptLevel) { 70894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return new BlackfinDAGToDAGISel(TM, OptLevel); 71894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 72894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 73894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid BlackfinDAGToDAGISel::PostprocessISelDAG() { 74894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FixRegisterClasses(*CurDAG); 75894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 76894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 77894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDNode *BlackfinDAGToDAGISel::Select(SDNode *N) { 78894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (N->isMachineOpcode()) 79894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return NULL; // Already selected. 80894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 81894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (N->getOpcode()) { 82894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: break; 83894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FrameIndex: { 84894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Selects to ADDpp FI, 0 which in turn will become ADDimm7 SP, imm or ADDpp 85894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // SP, Px 86894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int FI = cast<FrameIndexSDNode>(N)->getIndex(); 87894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue TFI = CurDAG->getTargetFrameIndex(FI, MVT::i32); 88894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return CurDAG->SelectNodeTo(N, BF::ADDpp, MVT::i32, TFI, 89894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CurDAG->getTargetConstant(0, MVT::i32)); 90894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 91894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 92894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 93894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SelectCode(N); 94894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 95894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 9619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool BlackfinDAGToDAGISel::SelectADDRspii(SDValue Addr, 97894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &Base, 98894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &Offset) { 99894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FrameIndexSDNode *FIN = 0; 100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if ((FIN = dyn_cast<FrameIndexSDNode>(Addr))) { 101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Offset = CurDAG->getTargetConstant(0, MVT::i32); 103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Addr.getOpcode() == ISD::ADD) { 106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ConstantSDNode *CN = 0; 107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if ((FIN = dyn_cast<FrameIndexSDNode>(Addr.getOperand(0))) && 108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman (CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) && 109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman (CN->getSExtValue() % 4 == 0 && CN->getSExtValue() >= 0)) { 110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Constant positive word offset from frame index 111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Offset = CurDAG->getTargetConstant(CN->getSExtValue(), MVT::i32); 113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic inline bool isCC(const TargetRegisterClass *RC) { 12019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return BF::AnyCCRegClass.hasSubClassEq(RC); 121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic inline bool isDCC(const TargetRegisterClass *RC) { 12419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return BF::DRegClass.hasSubClassEq(RC) || isCC(RC); 125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 126894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic void UpdateNodeOperand(SelectionDAG &DAG, 128894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *N, 129894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Num, 130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Val) { 131894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallVector<SDValue, 8> ops(N->op_begin(), N->op_end()); 132894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ops[Num] = Val; 133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *New = DAG.UpdateNodeOperands(N, ops.data(), ops.size()); 134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.ReplaceAllUsesWith(N, New); 135894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 136894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 137894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// After instruction selection, insert COPY_TO_REGCLASS nodes to help in 138894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// choosing the proper register classes. 139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid BlackfinDAGToDAGISel::FixRegisterClasses(SelectionDAG &DAG) { 140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const BlackfinInstrInfo &TII = getInstrInfo(); 141894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const BlackfinRegisterInfo *TRI = getRegisterInfo(); 142894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.AssignTopologicalOrder(); 143894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman HandleSDNode Dummy(DAG.getRoot()); 144894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 145894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (SelectionDAG::allnodes_iterator NI = DAG.allnodes_begin(); 146894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NI != DAG.allnodes_end(); ++NI) { 147894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (NI->use_empty() || !NI->isMachineOpcode()) 148894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman continue; 14919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const MCInstrDesc &DefMCID = TII.get(NI->getMachineOpcode()); 150894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (SDNode::use_iterator UI = NI->use_begin(); !UI.atEnd(); ++UI) { 151894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!UI->isMachineOpcode()) 152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman continue; 153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 15419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (UI.getUse().getResNo() >= DefMCID.getNumDefs()) 155894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman continue; 156894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const TargetRegisterClass *DefRC = 15719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TII.getRegClass(DefMCID, UI.getUse().getResNo(), TRI); 158894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 15919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const MCInstrDesc &UseMCID = TII.get(UI->getMachineOpcode()); 16019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (UseMCID.getNumDefs()+UI.getOperandNo() >= UseMCID.getNumOperands()) 161894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman continue; 162894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const TargetRegisterClass *UseRC = 16319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TII.getRegClass(UseMCID, UseMCID.getNumDefs()+UI.getOperandNo(), TRI); 164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!DefRC || !UseRC) 165894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman continue; 166894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // We cannot copy CC <-> !(CC/D) 167894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if ((isCC(DefRC) && !isDCC(UseRC)) || (isCC(UseRC) && !isDCC(DefRC))) { 168894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *Copy = 169894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getMachineNode(TargetOpcode::COPY_TO_REGCLASS, 170894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NI->getDebugLoc(), 171894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MVT::i32, 172894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman UI.getUse().get(), 173894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getTargetConstant(BF::DRegClassID, MVT::i32)); 174894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman UpdateNodeOperand(DAG, *UI, UI.getOperandNo(), SDValue(Copy, 0)); 175894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 176894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 177894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 178894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.setRoot(Dummy.getValue()); 179894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 180894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 181