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