150880d08ec32857fa557281046c81a0506e7f64dEric Christopher//===-- PTXISelDAGToDAG.cpp - A dag to dag inst selector for PTX ----------===// 250880d08ec32857fa557281046c81a0506e7f64dEric Christopher// 350880d08ec32857fa557281046c81a0506e7f64dEric Christopher// The LLVM Compiler Infrastructure 450880d08ec32857fa557281046c81a0506e7f64dEric Christopher// 550880d08ec32857fa557281046c81a0506e7f64dEric Christopher// This file is distributed under the University of Illinois Open Source 650880d08ec32857fa557281046c81a0506e7f64dEric Christopher// License. See LICENSE.TXT for details. 750880d08ec32857fa557281046c81a0506e7f64dEric Christopher// 850880d08ec32857fa557281046c81a0506e7f64dEric Christopher//===----------------------------------------------------------------------===// 950880d08ec32857fa557281046c81a0506e7f64dEric Christopher// 1050880d08ec32857fa557281046c81a0506e7f64dEric Christopher// This file defines an instruction selector for the PTX target. 1150880d08ec32857fa557281046c81a0506e7f64dEric Christopher// 1250880d08ec32857fa557281046c81a0506e7f64dEric Christopher//===----------------------------------------------------------------------===// 1350880d08ec32857fa557281046c81a0506e7f64dEric Christopher 1450880d08ec32857fa557281046c81a0506e7f64dEric Christopher#include "PTX.h" 15f47dfba023ec6db12cdfac0578c4d8229aecc2e4Justin Holewinski#include "PTXMachineFunctionInfo.h" 1650880d08ec32857fa557281046c81a0506e7f64dEric Christopher#include "PTXTargetMachine.h" 17f47dfba023ec6db12cdfac0578c4d8229aecc2e4Justin Holewinski#include "llvm/ADT/StringExtras.h" 1850880d08ec32857fa557281046c81a0506e7f64dEric Christopher#include "llvm/CodeGen/SelectionDAGISel.h" 193f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou#include "llvm/DerivedTypes.h" 2067a918486132309f224d152188747ca5e7f224caJustin Holewinski#include "llvm/Support/Debug.h" 21fd8978b021dbb0b9b09084dcc707c2054ff76280Che-Liang Chiou#include "llvm/Support/raw_ostream.h" 2250880d08ec32857fa557281046c81a0506e7f64dEric Christopher 2350880d08ec32857fa557281046c81a0506e7f64dEric Christopherusing namespace llvm; 2450880d08ec32857fa557281046c81a0506e7f64dEric Christopher 2550880d08ec32857fa557281046c81a0506e7f64dEric Christophernamespace { 2650880d08ec32857fa557281046c81a0506e7f64dEric Christopher// PTXDAGToDAGISel - PTX specific code to select PTX machine 2750880d08ec32857fa557281046c81a0506e7f64dEric Christopher// instructions for SelectionDAG operations. 2850880d08ec32857fa557281046c81a0506e7f64dEric Christopherclass PTXDAGToDAGISel : public SelectionDAGISel { 2950880d08ec32857fa557281046c81a0506e7f64dEric Christopher public: 3050880d08ec32857fa557281046c81a0506e7f64dEric Christopher PTXDAGToDAGISel(PTXTargetMachine &TM, CodeGenOpt::Level OptLevel); 3150880d08ec32857fa557281046c81a0506e7f64dEric Christopher 3250880d08ec32857fa557281046c81a0506e7f64dEric Christopher virtual const char *getPassName() const { 3350880d08ec32857fa557281046c81a0506e7f64dEric Christopher return "PTX DAG->DAG Pattern Instruction Selection"; 3450880d08ec32857fa557281046c81a0506e7f64dEric Christopher } 3550880d08ec32857fa557281046c81a0506e7f64dEric Christopher 3650880d08ec32857fa557281046c81a0506e7f64dEric Christopher SDNode *Select(SDNode *Node); 3750880d08ec32857fa557281046c81a0506e7f64dEric Christopher 383f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou // Complex Pattern Selectors. 39fc7072c3c4db03555a0a62220d61a2b85acd01fdChe-Liang Chiou bool SelectADDRrr(SDValue &Addr, SDValue &R1, SDValue &R2); 403f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou bool SelectADDRri(SDValue &Addr, SDValue &Base, SDValue &Offset); 413f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou bool SelectADDRii(SDValue &Addr, SDValue &Base, SDValue &Offset); 426b8990df42c3e9814cc60c3072f85b5a38bbb410Justin Holewinski bool SelectADDRlocal(SDValue &Addr, SDValue &Base, SDValue &Offset); 433f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou 4450880d08ec32857fa557281046c81a0506e7f64dEric Christopher // Include the pieces auto'gened from the target description 4550880d08ec32857fa557281046c81a0506e7f64dEric Christopher#include "PTXGenDAGISel.inc" 4650880d08ec32857fa557281046c81a0506e7f64dEric Christopher 473f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou private: 4888d3367baa066b4924a9303291aee084c154fff1Che-Liang Chiou // We need this only because we can't match intruction BRAdp 4988d3367baa066b4924a9303291aee084c154fff1Che-Liang Chiou // pattern (PTXbrcond bb:$d, ...) in PTXInstrInfo.td 5088d3367baa066b4924a9303291aee084c154fff1Che-Liang Chiou SDNode *SelectBRCOND(SDNode *Node); 5188d3367baa066b4924a9303291aee084c154fff1Che-Liang Chiou 525422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski SDNode *SelectREADPARAM(SDNode *Node); 535422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski SDNode *SelectWRITEPARAM(SDNode *Node); 546b8990df42c3e9814cc60c3072f85b5a38bbb410Justin Holewinski SDNode *SelectFrameIndex(SDNode *Node); 555422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski 56fc7072c3c4db03555a0a62220d61a2b85acd01fdChe-Liang Chiou bool isImm(const SDValue &operand); 57fc7072c3c4db03555a0a62220d61a2b85acd01fdChe-Liang Chiou bool SelectImm(const SDValue &operand, SDValue &imm); 58f48817cbf98472c4007e38ff7dad57126531a6e0Che-Liang Chiou 59f48817cbf98472c4007e38ff7dad57126531a6e0Che-Liang Chiou const PTXSubtarget& getSubtarget() const; 6050880d08ec32857fa557281046c81a0506e7f64dEric Christopher}; // class PTXDAGToDAGISel 6150880d08ec32857fa557281046c81a0506e7f64dEric Christopher} // namespace 6250880d08ec32857fa557281046c81a0506e7f64dEric Christopher 6350880d08ec32857fa557281046c81a0506e7f64dEric Christopher// createPTXISelDag - This pass converts a legalized DAG into a 6450880d08ec32857fa557281046c81a0506e7f64dEric Christopher// PTX-specific DAG, ready for instruction scheduling 6550880d08ec32857fa557281046c81a0506e7f64dEric ChristopherFunctionPass *llvm::createPTXISelDag(PTXTargetMachine &TM, 6650880d08ec32857fa557281046c81a0506e7f64dEric Christopher CodeGenOpt::Level OptLevel) { 6750880d08ec32857fa557281046c81a0506e7f64dEric Christopher return new PTXDAGToDAGISel(TM, OptLevel); 6850880d08ec32857fa557281046c81a0506e7f64dEric Christopher} 6950880d08ec32857fa557281046c81a0506e7f64dEric Christopher 7050880d08ec32857fa557281046c81a0506e7f64dEric ChristopherPTXDAGToDAGISel::PTXDAGToDAGISel(PTXTargetMachine &TM, 7150880d08ec32857fa557281046c81a0506e7f64dEric Christopher CodeGenOpt::Level OptLevel) 7250880d08ec32857fa557281046c81a0506e7f64dEric Christopher : SelectionDAGISel(TM, OptLevel) {} 7350880d08ec32857fa557281046c81a0506e7f64dEric Christopher 7450880d08ec32857fa557281046c81a0506e7f64dEric ChristopherSDNode *PTXDAGToDAGISel::Select(SDNode *Node) { 7588d3367baa066b4924a9303291aee084c154fff1Che-Liang Chiou switch (Node->getOpcode()) { 7688d3367baa066b4924a9303291aee084c154fff1Che-Liang Chiou case ISD::BRCOND: 7788d3367baa066b4924a9303291aee084c154fff1Che-Liang Chiou return SelectBRCOND(Node); 785422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski case PTXISD::READ_PARAM: 795422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski return SelectREADPARAM(Node); 805422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski case PTXISD::WRITE_PARAM: 815422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski return SelectWRITEPARAM(Node); 826b8990df42c3e9814cc60c3072f85b5a38bbb410Justin Holewinski case ISD::FrameIndex: 836b8990df42c3e9814cc60c3072f85b5a38bbb410Justin Holewinski return SelectFrameIndex(Node); 8488d3367baa066b4924a9303291aee084c154fff1Che-Liang Chiou default: 8588d3367baa066b4924a9303291aee084c154fff1Che-Liang Chiou return SelectCode(Node); 8688d3367baa066b4924a9303291aee084c154fff1Che-Liang Chiou } 878e5d01cd6efa99a26c8584711a7e8abbcf14c333Che-Liang Chiou} 888e5d01cd6efa99a26c8584711a7e8abbcf14c333Che-Liang Chiou 8988d3367baa066b4924a9303291aee084c154fff1Che-Liang ChiouSDNode *PTXDAGToDAGISel::SelectBRCOND(SDNode *Node) { 9088d3367baa066b4924a9303291aee084c154fff1Che-Liang Chiou assert(Node->getNumOperands() >= 3); 9188d3367baa066b4924a9303291aee084c154fff1Che-Liang Chiou 9288d3367baa066b4924a9303291aee084c154fff1Che-Liang Chiou SDValue Chain = Node->getOperand(0); 9388d3367baa066b4924a9303291aee084c154fff1Che-Liang Chiou SDValue Pred = Node->getOperand(1); 9488d3367baa066b4924a9303291aee084c154fff1Che-Liang Chiou SDValue Target = Node->getOperand(2); // branch target 95f51b7e5d74d3de591c61e5cd69bb1b55c471c7d4Justin Holewinski SDValue PredOp = CurDAG->getTargetConstant(PTXPredicate::Normal, MVT::i32); 9688d3367baa066b4924a9303291aee084c154fff1Che-Liang Chiou DebugLoc dl = Node->getDebugLoc(); 9788d3367baa066b4924a9303291aee084c154fff1Che-Liang Chiou 9888d3367baa066b4924a9303291aee084c154fff1Che-Liang Chiou assert(Target.getOpcode() == ISD::BasicBlock); 9988d3367baa066b4924a9303291aee084c154fff1Che-Liang Chiou assert(Pred.getValueType() == MVT::i1); 10088d3367baa066b4924a9303291aee084c154fff1Che-Liang Chiou 10188d3367baa066b4924a9303291aee084c154fff1Che-Liang Chiou // Emit BRAdp 10288d3367baa066b4924a9303291aee084c154fff1Che-Liang Chiou SDValue Ops[] = { Target, Pred, PredOp, Chain }; 10388d3367baa066b4924a9303291aee084c154fff1Che-Liang Chiou return CurDAG->getMachineNode(PTX::BRAdp, dl, MVT::Other, Ops, 4); 10488d3367baa066b4924a9303291aee084c154fff1Che-Liang Chiou} 10588d3367baa066b4924a9303291aee084c154fff1Che-Liang Chiou 1065422a0f166bc86c72fafaa547435e18578add3b9Justin HolewinskiSDNode *PTXDAGToDAGISel::SelectREADPARAM(SDNode *Node) { 1075422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski SDValue Chain = Node->getOperand(0); 1085422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski SDValue Index = Node->getOperand(1); 1095422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski 1105422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski int OpCode; 1115422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski 1125422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski // Get the type of parameter we are reading 1135422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski EVT VT = Node->getValueType(0); 1145422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski assert(VT.isSimple() && "READ_PARAM only implemented for MVT types"); 1155422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski 1165422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski MVT Type = VT.getSimpleVT(); 1175422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski 1185422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski if (Type == MVT::i1) 1195422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski OpCode = PTX::READPARAMPRED; 1205422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski else if (Type == MVT::i16) 1215422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski OpCode = PTX::READPARAMI16; 1225422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski else if (Type == MVT::i32) 1235422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski OpCode = PTX::READPARAMI32; 1245422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski else if (Type == MVT::i64) 1255422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski OpCode = PTX::READPARAMI64; 1265422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski else if (Type == MVT::f32) 1275422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski OpCode = PTX::READPARAMF32; 12862c607b74157eadd78679434bb92d82f347d0bc1Duncan Sands else { 12962c607b74157eadd78679434bb92d82f347d0bc1Duncan Sands assert(Type == MVT::f64 && "Unexpected type!"); 1305422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski OpCode = PTX::READPARAMF64; 13162c607b74157eadd78679434bb92d82f347d0bc1Duncan Sands } 1325422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski 1335422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski SDValue Pred = CurDAG->getRegister(PTX::NoRegister, MVT::i1); 134f51b7e5d74d3de591c61e5cd69bb1b55c471c7d4Justin Holewinski SDValue PredOp = CurDAG->getTargetConstant(PTXPredicate::None, MVT::i32); 1355422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski DebugLoc dl = Node->getDebugLoc(); 1365422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski 1375422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski SDValue Ops[] = { Index, Pred, PredOp, Chain }; 1385422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski return CurDAG->getMachineNode(OpCode, dl, VT, Ops, 4); 1395422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski} 1405422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski 1415422a0f166bc86c72fafaa547435e18578add3b9Justin HolewinskiSDNode *PTXDAGToDAGISel::SelectWRITEPARAM(SDNode *Node) { 1425422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski 1435422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski SDValue Chain = Node->getOperand(0); 1445422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski SDValue Value = Node->getOperand(1); 1455422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski 1465422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski int OpCode; 1475422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski 1485422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski //Node->dumpr(CurDAG); 1495422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski 1505422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski // Get the type of parameter we are writing 1515422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski EVT VT = Value->getValueType(0); 1525422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski assert(VT.isSimple() && "WRITE_PARAM only implemented for MVT types"); 1535422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski 1545422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski MVT Type = VT.getSimpleVT(); 1555422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski 1565422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski if (Type == MVT::i1) 1575422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski OpCode = PTX::WRITEPARAMPRED; 1585422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski else if (Type == MVT::i16) 1595422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski OpCode = PTX::WRITEPARAMI16; 1605422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski else if (Type == MVT::i32) 1615422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski OpCode = PTX::WRITEPARAMI32; 1625422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski else if (Type == MVT::i64) 1635422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski OpCode = PTX::WRITEPARAMI64; 1645422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski else if (Type == MVT::f32) 1655422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski OpCode = PTX::WRITEPARAMF32; 1665422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski else if (Type == MVT::f64) 1675422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski OpCode = PTX::WRITEPARAMF64; 1685422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski else 1695422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski llvm_unreachable("Invalid type in SelectWRITEPARAM"); 1705422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski 1715422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski SDValue Pred = CurDAG->getRegister(PTX::NoRegister, MVT::i1); 172f51b7e5d74d3de591c61e5cd69bb1b55c471c7d4Justin Holewinski SDValue PredOp = CurDAG->getTargetConstant(PTXPredicate::None, MVT::i32); 1735422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski DebugLoc dl = Node->getDebugLoc(); 1745422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski 1755422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski SDValue Ops[] = { Value, Pred, PredOp, Chain }; 1765422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski SDNode* Ret = CurDAG->getMachineNode(OpCode, dl, MVT::Other, Ops, 4); 1775422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski 1785422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski //dbgs() << "SelectWRITEPARAM produced:\n\t"; 1795422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski //Ret->dumpr(CurDAG); 1805422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski 1815422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski return Ret; 1825422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski} 1835422a0f166bc86c72fafaa547435e18578add3b9Justin Holewinski 1846b8990df42c3e9814cc60c3072f85b5a38bbb410Justin HolewinskiSDNode *PTXDAGToDAGISel::SelectFrameIndex(SDNode *Node) { 1856b8990df42c3e9814cc60c3072f85b5a38bbb410Justin Holewinski int FI = cast<FrameIndexSDNode>(Node)->getIndex(); 1866b8990df42c3e9814cc60c3072f85b5a38bbb410Justin Holewinski //dbgs() << "Selecting FrameIndex at index " << FI << "\n"; 187f47dfba023ec6db12cdfac0578c4d8229aecc2e4Justin Holewinski //SDValue TFI = CurDAG->getTargetFrameIndex(FI, Node->getValueType(0)); 1886b8990df42c3e9814cc60c3072f85b5a38bbb410Justin Holewinski 189f47dfba023ec6db12cdfac0578c4d8229aecc2e4Justin Holewinski PTXMachineFunctionInfo *MFI = MF->getInfo<PTXMachineFunctionInfo>(); 1906b8990df42c3e9814cc60c3072f85b5a38bbb410Justin Holewinski 191f47dfba023ec6db12cdfac0578c4d8229aecc2e4Justin Holewinski SDValue FrameSymbol = CurDAG->getTargetExternalSymbol(MFI->getFrameSymbol(FI), 192f47dfba023ec6db12cdfac0578c4d8229aecc2e4Justin Holewinski Node->getValueType(0)); 1936b8990df42c3e9814cc60c3072f85b5a38bbb410Justin Holewinski 194f47dfba023ec6db12cdfac0578c4d8229aecc2e4Justin Holewinski return FrameSymbol.getNode(); 1956b8990df42c3e9814cc60c3072f85b5a38bbb410Justin Holewinski} 1966b8990df42c3e9814cc60c3072f85b5a38bbb410Justin Holewinski 197fc7072c3c4db03555a0a62220d61a2b85acd01fdChe-Liang Chiou// Match memory operand of the form [reg+reg] 198fc7072c3c4db03555a0a62220d61a2b85acd01fdChe-Liang Chioubool PTXDAGToDAGISel::SelectADDRrr(SDValue &Addr, SDValue &R1, SDValue &R2) { 199fc7072c3c4db03555a0a62220d61a2b85acd01fdChe-Liang Chiou if (Addr.getOpcode() != ISD::ADD || Addr.getNumOperands() < 2 || 200fc7072c3c4db03555a0a62220d61a2b85acd01fdChe-Liang Chiou isImm(Addr.getOperand(0)) || isImm(Addr.getOperand(1))) 201fc7072c3c4db03555a0a62220d61a2b85acd01fdChe-Liang Chiou return false; 202fc7072c3c4db03555a0a62220d61a2b85acd01fdChe-Liang Chiou 203d662576671cba43988ff2753e1d006e50c568241Justin Holewinski assert(Addr.getValueType().isSimple() && "Type must be simple"); 204d662576671cba43988ff2753e1d006e50c568241Justin Holewinski 205c88e91b875fc85ecc3e0d0f51b4a71dca9f29012Che-Liang Chiou R1 = Addr; 206d662576671cba43988ff2753e1d006e50c568241Justin Holewinski R2 = CurDAG->getTargetConstant(0, Addr.getValueType().getSimpleVT()); 207d662576671cba43988ff2753e1d006e50c568241Justin Holewinski 208fc7072c3c4db03555a0a62220d61a2b85acd01fdChe-Liang Chiou return true; 209fc7072c3c4db03555a0a62220d61a2b85acd01fdChe-Liang Chiou} 210fc7072c3c4db03555a0a62220d61a2b85acd01fdChe-Liang Chiou 211fc7072c3c4db03555a0a62220d61a2b85acd01fdChe-Liang Chiou// Match memory operand of the form [reg], [imm+reg], and [reg+imm] 2123f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chioubool PTXDAGToDAGISel::SelectADDRri(SDValue &Addr, SDValue &Base, 2133f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou SDValue &Offset) { 21463602ed8769afc21e7085d95263475c6669deaafJustin Holewinski // FrameIndex addresses are handled separately 21563602ed8769afc21e7085d95263475c6669deaafJustin Holewinski //errs() << "SelectADDRri: "; 21663602ed8769afc21e7085d95263475c6669deaafJustin Holewinski //Addr.getNode()->dumpr(); 21763602ed8769afc21e7085d95263475c6669deaafJustin Holewinski if (isa<FrameIndexSDNode>(Addr)) { 21863602ed8769afc21e7085d95263475c6669deaafJustin Holewinski //errs() << "Failure\n"; 21963602ed8769afc21e7085d95263475c6669deaafJustin Holewinski return false; 22063602ed8769afc21e7085d95263475c6669deaafJustin Holewinski } 22163602ed8769afc21e7085d95263475c6669deaafJustin Holewinski 22263602ed8769afc21e7085d95263475c6669deaafJustin Holewinski if (CurDAG->isBaseWithConstantOffset(Addr)) { 22363602ed8769afc21e7085d95263475c6669deaafJustin Holewinski Base = Addr.getOperand(0); 22463602ed8769afc21e7085d95263475c6669deaafJustin Holewinski if (isa<FrameIndexSDNode>(Base)) { 22563602ed8769afc21e7085d95263475c6669deaafJustin Holewinski //errs() << "Failure\n"; 22663602ed8769afc21e7085d95263475c6669deaafJustin Holewinski return false; 22763602ed8769afc21e7085d95263475c6669deaafJustin Holewinski } 22863602ed8769afc21e7085d95263475c6669deaafJustin Holewinski ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)); 22963602ed8769afc21e7085d95263475c6669deaafJustin Holewinski Offset = CurDAG->getTargetConstant(CN->getZExtValue(), MVT::i32); 23063602ed8769afc21e7085d95263475c6669deaafJustin Holewinski //errs() << "Success\n"; 23163602ed8769afc21e7085d95263475c6669deaafJustin Holewinski return true; 23263602ed8769afc21e7085d95263475c6669deaafJustin Holewinski } 23363602ed8769afc21e7085d95263475c6669deaafJustin Holewinski 23463602ed8769afc21e7085d95263475c6669deaafJustin Holewinski /*if (Addr.getNumOperands() == 1) { 23563602ed8769afc21e7085d95263475c6669deaafJustin Holewinski Base = Addr; 23663602ed8769afc21e7085d95263475c6669deaafJustin Holewinski Offset = CurDAG->getTargetConstant(0, Addr.getValueType().getSimpleVT()); 23763602ed8769afc21e7085d95263475c6669deaafJustin Holewinski errs() << "Success\n"; 23863602ed8769afc21e7085d95263475c6669deaafJustin Holewinski return true; 23963602ed8769afc21e7085d95263475c6669deaafJustin Holewinski }*/ 24063602ed8769afc21e7085d95263475c6669deaafJustin Holewinski 24163602ed8769afc21e7085d95263475c6669deaafJustin Holewinski //errs() << "SelectADDRri fails on: "; 24263602ed8769afc21e7085d95263475c6669deaafJustin Holewinski //Addr.getNode()->dumpr(); 24363602ed8769afc21e7085d95263475c6669deaafJustin Holewinski 24463602ed8769afc21e7085d95263475c6669deaafJustin Holewinski if (isImm(Addr)) { 24563602ed8769afc21e7085d95263475c6669deaafJustin Holewinski //errs() << "Failure\n"; 24663602ed8769afc21e7085d95263475c6669deaafJustin Holewinski return false; 24763602ed8769afc21e7085d95263475c6669deaafJustin Holewinski } 24863602ed8769afc21e7085d95263475c6669deaafJustin Holewinski 24963602ed8769afc21e7085d95263475c6669deaafJustin Holewinski Base = Addr; 25063602ed8769afc21e7085d95263475c6669deaafJustin Holewinski Offset = CurDAG->getTargetConstant(0, Addr.getValueType().getSimpleVT()); 25163602ed8769afc21e7085d95263475c6669deaafJustin Holewinski 25263602ed8769afc21e7085d95263475c6669deaafJustin Holewinski //errs() << "Success\n"; 25363602ed8769afc21e7085d95263475c6669deaafJustin Holewinski return true; 25463602ed8769afc21e7085d95263475c6669deaafJustin Holewinski 25563602ed8769afc21e7085d95263475c6669deaafJustin Holewinski /*if (Addr.getOpcode() != ISD::ADD) { 256c88e91b875fc85ecc3e0d0f51b4a71dca9f29012Che-Liang Chiou // let SelectADDRii handle the [imm] case 257fc7072c3c4db03555a0a62220d61a2b85acd01fdChe-Liang Chiou if (isImm(Addr)) 258fc7072c3c4db03555a0a62220d61a2b85acd01fdChe-Liang Chiou return false; 259c88e91b875fc85ecc3e0d0f51b4a71dca9f29012Che-Liang Chiou // it is [reg] 260d662576671cba43988ff2753e1d006e50c568241Justin Holewinski 261d662576671cba43988ff2753e1d006e50c568241Justin Holewinski assert(Addr.getValueType().isSimple() && "Type must be simple"); 262fc7072c3c4db03555a0a62220d61a2b85acd01fdChe-Liang Chiou Base = Addr; 263d662576671cba43988ff2753e1d006e50c568241Justin Holewinski Offset = CurDAG->getTargetConstant(0, Addr.getValueType().getSimpleVT()); 264d662576671cba43988ff2753e1d006e50c568241Justin Holewinski 265fc7072c3c4db03555a0a62220d61a2b85acd01fdChe-Liang Chiou return true; 266fc7072c3c4db03555a0a62220d61a2b85acd01fdChe-Liang Chiou } 267fc7072c3c4db03555a0a62220d61a2b85acd01fdChe-Liang Chiou 268c88e91b875fc85ecc3e0d0f51b4a71dca9f29012Che-Liang Chiou if (Addr.getNumOperands() < 2) 269c88e91b875fc85ecc3e0d0f51b4a71dca9f29012Che-Liang Chiou return false; 270c88e91b875fc85ecc3e0d0f51b4a71dca9f29012Che-Liang Chiou 271fc7072c3c4db03555a0a62220d61a2b85acd01fdChe-Liang Chiou // let SelectADDRii handle the [imm+imm] case 272c88e91b875fc85ecc3e0d0f51b4a71dca9f29012Che-Liang Chiou if (isImm(Addr.getOperand(0)) && isImm(Addr.getOperand(1))) 273fc7072c3c4db03555a0a62220d61a2b85acd01fdChe-Liang Chiou return false; 2743f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou 2753f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou // try [reg+imm] and [imm+reg] 276fc7072c3c4db03555a0a62220d61a2b85acd01fdChe-Liang Chiou for (int i = 0; i < 2; i ++) 277fc7072c3c4db03555a0a62220d61a2b85acd01fdChe-Liang Chiou if (SelectImm(Addr.getOperand(1-i), Offset)) { 278fc7072c3c4db03555a0a62220d61a2b85acd01fdChe-Liang Chiou Base = Addr.getOperand(i); 279fc7072c3c4db03555a0a62220d61a2b85acd01fdChe-Liang Chiou return true; 280fc7072c3c4db03555a0a62220d61a2b85acd01fdChe-Liang Chiou } 281fc7072c3c4db03555a0a62220d61a2b85acd01fdChe-Liang Chiou 282c88e91b875fc85ecc3e0d0f51b4a71dca9f29012Che-Liang Chiou // neither [reg+imm] nor [imm+reg] 28363602ed8769afc21e7085d95263475c6669deaafJustin Holewinski return false;*/ 2843f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou} 2853f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou 2863f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou// Match memory operand of the form [imm+imm] and [imm] 2873f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chioubool PTXDAGToDAGISel::SelectADDRii(SDValue &Addr, SDValue &Base, 2883f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou SDValue &Offset) { 289fc7072c3c4db03555a0a62220d61a2b85acd01fdChe-Liang Chiou // is [imm+imm]? 2903f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou if (Addr.getOpcode() == ISD::ADD) { 2913f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou return SelectImm(Addr.getOperand(0), Base) && 2923f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou SelectImm(Addr.getOperand(1), Offset); 2933f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou } 2943f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou 295fc7072c3c4db03555a0a62220d61a2b85acd01fdChe-Liang Chiou // is [imm]? 2963f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou if (SelectImm(Addr, Base)) { 297d662576671cba43988ff2753e1d006e50c568241Justin Holewinski assert(Addr.getValueType().isSimple() && "Type must be simple"); 298d662576671cba43988ff2753e1d006e50c568241Justin Holewinski 299d662576671cba43988ff2753e1d006e50c568241Justin Holewinski Offset = CurDAG->getTargetConstant(0, Addr.getValueType().getSimpleVT()); 300d662576671cba43988ff2753e1d006e50c568241Justin Holewinski 3013f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou return true; 3023f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou } 3033f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou 3043f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou return false; 3053f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou} 3063f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou 3076b8990df42c3e9814cc60c3072f85b5a38bbb410Justin Holewinski// Match memory operand of the form [reg], [imm+reg], and [reg+imm] 3086b8990df42c3e9814cc60c3072f85b5a38bbb410Justin Holewinskibool PTXDAGToDAGISel::SelectADDRlocal(SDValue &Addr, SDValue &Base, 3096b8990df42c3e9814cc60c3072f85b5a38bbb410Justin Holewinski SDValue &Offset) { 31063602ed8769afc21e7085d95263475c6669deaafJustin Holewinski //errs() << "SelectADDRlocal: "; 31163602ed8769afc21e7085d95263475c6669deaafJustin Holewinski //Addr.getNode()->dumpr(); 31263602ed8769afc21e7085d95263475c6669deaafJustin Holewinski if (isa<FrameIndexSDNode>(Addr)) { 3136b8990df42c3e9814cc60c3072f85b5a38bbb410Justin Holewinski Base = Addr; 3146b8990df42c3e9814cc60c3072f85b5a38bbb410Justin Holewinski Offset = CurDAG->getTargetConstant(0, Addr.getValueType().getSimpleVT()); 31563602ed8769afc21e7085d95263475c6669deaafJustin Holewinski //errs() << "Success\n"; 3166b8990df42c3e9814cc60c3072f85b5a38bbb410Justin Holewinski return true; 3176b8990df42c3e9814cc60c3072f85b5a38bbb410Justin Holewinski } 3186b8990df42c3e9814cc60c3072f85b5a38bbb410Justin Holewinski 31963602ed8769afc21e7085d95263475c6669deaafJustin Holewinski if (CurDAG->isBaseWithConstantOffset(Addr)) { 32063602ed8769afc21e7085d95263475c6669deaafJustin Holewinski Base = Addr.getOperand(0); 32163602ed8769afc21e7085d95263475c6669deaafJustin Holewinski if (!isa<FrameIndexSDNode>(Base)) { 32263602ed8769afc21e7085d95263475c6669deaafJustin Holewinski //errs() << "Failure\n"; 32363602ed8769afc21e7085d95263475c6669deaafJustin Holewinski return false; 3246b8990df42c3e9814cc60c3072f85b5a38bbb410Justin Holewinski } 32563602ed8769afc21e7085d95263475c6669deaafJustin Holewinski ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)); 32663602ed8769afc21e7085d95263475c6669deaafJustin Holewinski Offset = CurDAG->getTargetConstant(CN->getZExtValue(), MVT::i32); 32763602ed8769afc21e7085d95263475c6669deaafJustin Holewinski //errs() << "Offset: "; 32863602ed8769afc21e7085d95263475c6669deaafJustin Holewinski //Offset.getNode()->dumpr(); 32963602ed8769afc21e7085d95263475c6669deaafJustin Holewinski //errs() << "Success\n"; 33063602ed8769afc21e7085d95263475c6669deaafJustin Holewinski return true; 33163602ed8769afc21e7085d95263475c6669deaafJustin Holewinski } 3326b8990df42c3e9814cc60c3072f85b5a38bbb410Justin Holewinski 33363602ed8769afc21e7085d95263475c6669deaafJustin Holewinski //errs() << "Failure\n"; 3346b8990df42c3e9814cc60c3072f85b5a38bbb410Justin Holewinski return false; 3356b8990df42c3e9814cc60c3072f85b5a38bbb410Justin Holewinski} 3366b8990df42c3e9814cc60c3072f85b5a38bbb410Justin Holewinski 3373f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chioubool PTXDAGToDAGISel::isImm(const SDValue &operand) { 3383f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou return ConstantSDNode::classof(operand.getNode()); 3393f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou} 3403f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou 3413f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chioubool PTXDAGToDAGISel::SelectImm(const SDValue &operand, SDValue &imm) { 3423f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou SDNode *node = operand.getNode(); 3433f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou if (!ConstantSDNode::classof(node)) 3443f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou return false; 3453f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou 3463f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou ConstantSDNode *CN = cast<ConstantSDNode>(node); 347d662576671cba43988ff2753e1d006e50c568241Justin Holewinski imm = CurDAG->getTargetConstant(*CN->getConstantIntValue(), 348d662576671cba43988ff2753e1d006e50c568241Justin Holewinski operand.getValueType()); 3493f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou return true; 3503f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou} 351f48817cbf98472c4007e38ff7dad57126531a6e0Che-Liang Chiou 352f48817cbf98472c4007e38ff7dad57126531a6e0Che-Liang Chiouconst PTXSubtarget& PTXDAGToDAGISel::getSubtarget() const 353f48817cbf98472c4007e38ff7dad57126531a6e0Che-Liang Chiou{ 354f48817cbf98472c4007e38ff7dad57126531a6e0Che-Liang Chiou return TM.getSubtarget<PTXSubtarget>(); 355f48817cbf98472c4007e38ff7dad57126531a6e0Che-Liang Chiou} 356f48817cbf98472c4007e38ff7dad57126531a6e0Che-Liang Chiou 357