PTXISelDAGToDAG.cpp revision 3f8e61789100ee411d0bfe00fb90df60eaed65f5
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"
1550880d08ec32857fa557281046c81a0506e7f64dEric Christopher#include "PTXTargetMachine.h"
1650880d08ec32857fa557281046c81a0506e7f64dEric Christopher#include "llvm/CodeGen/SelectionDAGISel.h"
173f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou#include "llvm/DerivedTypes.h"
1850880d08ec32857fa557281046c81a0506e7f64dEric Christopher
1950880d08ec32857fa557281046c81a0506e7f64dEric Christopherusing namespace llvm;
2050880d08ec32857fa557281046c81a0506e7f64dEric Christopher
2150880d08ec32857fa557281046c81a0506e7f64dEric Christophernamespace {
2250880d08ec32857fa557281046c81a0506e7f64dEric Christopher// PTXDAGToDAGISel - PTX specific code to select PTX machine
2350880d08ec32857fa557281046c81a0506e7f64dEric Christopher// instructions for SelectionDAG operations.
2450880d08ec32857fa557281046c81a0506e7f64dEric Christopherclass PTXDAGToDAGISel : public SelectionDAGISel {
2550880d08ec32857fa557281046c81a0506e7f64dEric Christopher  public:
2650880d08ec32857fa557281046c81a0506e7f64dEric Christopher    PTXDAGToDAGISel(PTXTargetMachine &TM, CodeGenOpt::Level OptLevel);
2750880d08ec32857fa557281046c81a0506e7f64dEric Christopher
2850880d08ec32857fa557281046c81a0506e7f64dEric Christopher    virtual const char *getPassName() const {
2950880d08ec32857fa557281046c81a0506e7f64dEric Christopher      return "PTX DAG->DAG Pattern Instruction Selection";
3050880d08ec32857fa557281046c81a0506e7f64dEric Christopher    }
3150880d08ec32857fa557281046c81a0506e7f64dEric Christopher
3250880d08ec32857fa557281046c81a0506e7f64dEric Christopher    SDNode *Select(SDNode *Node);
3350880d08ec32857fa557281046c81a0506e7f64dEric Christopher
343f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou    // Complex Pattern Selectors.
353f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou    bool SelectADDRri(SDValue &Addr, SDValue &Base, SDValue &Offset);
363f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou    bool SelectADDRii(SDValue &Addr, SDValue &Base, SDValue &Offset);
373f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou
3850880d08ec32857fa557281046c81a0506e7f64dEric Christopher    // Include the pieces auto'gened from the target description
3950880d08ec32857fa557281046c81a0506e7f64dEric Christopher#include "PTXGenDAGISel.inc"
4050880d08ec32857fa557281046c81a0506e7f64dEric Christopher
413f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou  private:
423f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou    bool isImm (const SDValue &operand);
433f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou    bool SelectImm (const SDValue &operand, SDValue &imm);
4450880d08ec32857fa557281046c81a0506e7f64dEric Christopher}; // class PTXDAGToDAGISel
4550880d08ec32857fa557281046c81a0506e7f64dEric Christopher} // namespace
4650880d08ec32857fa557281046c81a0506e7f64dEric Christopher
4750880d08ec32857fa557281046c81a0506e7f64dEric Christopher// createPTXISelDag - This pass converts a legalized DAG into a
4850880d08ec32857fa557281046c81a0506e7f64dEric Christopher// PTX-specific DAG, ready for instruction scheduling
4950880d08ec32857fa557281046c81a0506e7f64dEric ChristopherFunctionPass *llvm::createPTXISelDag(PTXTargetMachine &TM,
5050880d08ec32857fa557281046c81a0506e7f64dEric Christopher                                     CodeGenOpt::Level OptLevel) {
5150880d08ec32857fa557281046c81a0506e7f64dEric Christopher  return new PTXDAGToDAGISel(TM, OptLevel);
5250880d08ec32857fa557281046c81a0506e7f64dEric Christopher}
5350880d08ec32857fa557281046c81a0506e7f64dEric Christopher
5450880d08ec32857fa557281046c81a0506e7f64dEric ChristopherPTXDAGToDAGISel::PTXDAGToDAGISel(PTXTargetMachine &TM,
5550880d08ec32857fa557281046c81a0506e7f64dEric Christopher                                 CodeGenOpt::Level OptLevel)
5650880d08ec32857fa557281046c81a0506e7f64dEric Christopher  : SelectionDAGISel(TM, OptLevel) {}
5750880d08ec32857fa557281046c81a0506e7f64dEric Christopher
5850880d08ec32857fa557281046c81a0506e7f64dEric ChristopherSDNode *PTXDAGToDAGISel::Select(SDNode *Node) {
5950880d08ec32857fa557281046c81a0506e7f64dEric Christopher  // SelectCode() is auto'gened
6050880d08ec32857fa557281046c81a0506e7f64dEric Christopher  return SelectCode(Node);
6150880d08ec32857fa557281046c81a0506e7f64dEric Christopher}
623f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou
633f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou// Match memory operand of the form [reg+reg] and [reg+imm]
643f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chioubool PTXDAGToDAGISel::SelectADDRri(SDValue &Addr, SDValue &Base,
653f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou                                   SDValue &Offset) {
663f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou  if (Addr.getNumOperands() >= 2 &&
673f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou      isImm(Addr.getOperand(0)) && isImm(Addr.getOperand(1)))
683f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou    return false; // let SelectADDRii handle the [imm+imm] case
693f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou
703f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou  // try [reg+imm] and [imm+reg]
713f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou  if (Addr.getOpcode() == ISD::ADD)
723f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou    for (int i = 0; i < 2; i ++)
733f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou      if (SelectImm(Addr.getOperand(1-i), Offset)) {
743f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou        Base = Addr.getOperand(i);
753f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou        return true;
763f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou      }
773f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou
783f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou  // okay, it's [reg+reg]
793f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou  Base = Addr;
803f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou  Offset = CurDAG->getTargetConstant(0, MVT::i32);
813f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou  return true;
823f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou}
833f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou
843f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou// Match memory operand of the form [imm+imm] and [imm]
853f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chioubool PTXDAGToDAGISel::SelectADDRii(SDValue &Addr, SDValue &Base,
863f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou                                   SDValue &Offset) {
873f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou  if (Addr.getOpcode() == ISD::ADD) {
883f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou    return SelectImm(Addr.getOperand(0), Base) &&
893f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou           SelectImm(Addr.getOperand(1), Offset);
903f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou  }
913f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou
923f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou  if (SelectImm(Addr, Base)) {
933f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou    Offset = CurDAG->getTargetConstant(0, MVT::i32);
943f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou    return true;
953f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou  }
963f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou
973f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou  return false;
983f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou}
993f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou
1003f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chioubool PTXDAGToDAGISel::isImm(const SDValue &operand) {
1013f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou  return ConstantSDNode::classof(operand.getNode());
1023f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou}
1033f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou
1043f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chioubool PTXDAGToDAGISel::SelectImm(const SDValue &operand, SDValue &imm) {
1053f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou  SDNode *node = operand.getNode();
1063f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou  if (!ConstantSDNode::classof(node))
1073f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou    return false;
1083f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou
1093f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou  ConstantSDNode *CN = cast<ConstantSDNode>(node);
1103f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou  imm = CurDAG->getTargetConstant(*CN->getConstantIntValue(), MVT::i32);
1113f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou  return true;
1123f8e61789100ee411d0bfe00fb90df60eaed65f5Che-Liang Chiou}
113