radeon/llvm: Move lowering of SETCC node to R600ISelLowering
[mesa.git] / src / gallium / drivers / radeon / AMDILISelDAGToDAG.cpp
index b8898828dd62b287b46745c608257a412c2b6ea7..df0ac75c8283abadef04e0d9675885f060ae8f08 100644 (file)
@@ -10,8 +10,8 @@
 // This file defines an instruction selector for the AMDIL target.
 //
 //===----------------------------------------------------------------------===//
+#include "AMDGPUISelLowering.h" // For AMDGPUISD
 #include "AMDILDevices.h"
-#include "AMDILTargetMachine.h"
 #include "AMDILUtilityFunctions.h"
 #include "llvm/ADT/ValueMap.h"
 #include "llvm/CodeGen/PseudoSourceValue.h"
@@ -36,7 +36,7 @@ class AMDILDAGToDAGISel : public SelectionDAGISel {
   // make the right decision when generating code for different targets.
   const AMDILSubtarget &Subtarget;
 public:
-  AMDILDAGToDAGISel(AMDILTargetMachine &TM AMDIL_OPT_LEVEL_DECL);
+  AMDILDAGToDAGISel(TargetMachine &TM AMDIL_OPT_LEVEL_DECL);
   virtual ~AMDILDAGToDAGISel();
 
   SDNode *Select(SDNode *N);
@@ -65,22 +65,24 @@ private:
   static bool isLocalLoad(const LoadSDNode *N);
   static bool isRegionLoad(const LoadSDNode *N);
 
-  SDNode *xformAtomicInst(SDNode *N);
+  bool SelectADDR8BitOffset(SDValue Addr, SDValue& Base, SDValue& Offset);
+  bool SelectADDRReg(SDValue Addr, SDValue& Base, SDValue& Offset);
+  bool SelectADDRVTX_READ(SDValue Addr, SDValue &Base, SDValue &Offset);
 
   // Include the pieces autogenerated from the target description.
-#include "AMDILGenDAGISel.inc"
+#include "AMDGPUGenDAGISel.inc"
 };
 }  // end anonymous namespace
 
 // createAMDILISelDag - This pass converts a legalized DAG into a AMDIL-specific
 // DAG, ready for instruction scheduling.
 //
-FunctionPass *llvm::createAMDILISelDag(AMDILTargetMachine &TM
+FunctionPass *llvm::createAMDILISelDag(TargetMachine &TM
                                         AMDIL_OPT_LEVEL_DECL) {
   return new AMDILDAGToDAGISel(TM AMDIL_OPT_LEVEL_VAR);
 }
 
-AMDILDAGToDAGISel::AMDILDAGToDAGISel(AMDILTargetMachine &TM
+AMDILDAGToDAGISel::AMDILDAGToDAGISel(TargetMachine &TM
                                       AMDIL_OPT_LEVEL_DECL)
   : SelectionDAGISel(TM AMDIL_OPT_LEVEL_VAR), Subtarget(TM.getSubtarget<AMDILSubtarget>())
 {
@@ -159,18 +161,13 @@ SDNode *AMDILDAGToDAGISel::Select(SDNode *N) {
       if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(N)) {
         unsigned int FI = FIN->getIndex();
         EVT OpVT = N->getValueType(0);
-        unsigned int NewOpc = AMDIL::MOVE_i32;
+        unsigned int NewOpc = AMDGPU::COPY;
         SDValue TFI = CurDAG->getTargetFrameIndex(FI, MVT::i32);
         return CurDAG->SelectNodeTo(N, NewOpc, OpVT, TFI);
       }
     }
     break;
   }
-  // For all atomic instructions, we need to add a constant
-  // operand that stores the resource ID in the instruction
-  if (Opc > AMDILISD::ADDADDR && Opc < AMDILISD::APPEND_ALLOC) {
-    N = xformAtomicInst(N);
-  }
   return SelectCode(N);
 }
 
@@ -309,207 +306,88 @@ const char *AMDILDAGToDAGISel::getPassName() const {
   return "AMDIL DAG->DAG Pattern Instruction Selection";
 }
 
-SDNode*
-AMDILDAGToDAGISel::xformAtomicInst(SDNode *N)
-{
-  uint32_t addVal = 1;
-  bool addOne = false;
-  // bool bitCastToInt = (N->getValueType(0) == MVT::f32);
-  unsigned opc = N->getOpcode();
-  switch (opc) {
-    default: return N;
-    case AMDILISD::ATOM_G_ADD:
-    case AMDILISD::ATOM_G_AND:
-    case AMDILISD::ATOM_G_MAX:
-    case AMDILISD::ATOM_G_UMAX:
-    case AMDILISD::ATOM_G_MIN:
-    case AMDILISD::ATOM_G_UMIN:
-    case AMDILISD::ATOM_G_OR:
-    case AMDILISD::ATOM_G_SUB:
-    case AMDILISD::ATOM_G_RSUB:
-    case AMDILISD::ATOM_G_XCHG:
-    case AMDILISD::ATOM_G_XOR:
-    case AMDILISD::ATOM_G_ADD_NORET:
-    case AMDILISD::ATOM_G_AND_NORET:
-    case AMDILISD::ATOM_G_MAX_NORET:
-    case AMDILISD::ATOM_G_UMAX_NORET:
-    case AMDILISD::ATOM_G_MIN_NORET:
-    case AMDILISD::ATOM_G_UMIN_NORET:
-    case AMDILISD::ATOM_G_OR_NORET:
-    case AMDILISD::ATOM_G_SUB_NORET:
-    case AMDILISD::ATOM_G_RSUB_NORET:
-    case AMDILISD::ATOM_G_XCHG_NORET:
-    case AMDILISD::ATOM_G_XOR_NORET:
-    case AMDILISD::ATOM_L_ADD:
-    case AMDILISD::ATOM_L_AND:
-    case AMDILISD::ATOM_L_MAX:
-    case AMDILISD::ATOM_L_UMAX:
-    case AMDILISD::ATOM_L_MIN:
-    case AMDILISD::ATOM_L_UMIN:
-    case AMDILISD::ATOM_L_OR:
-    case AMDILISD::ATOM_L_SUB:
-    case AMDILISD::ATOM_L_RSUB:
-    case AMDILISD::ATOM_L_XCHG:
-    case AMDILISD::ATOM_L_XOR:
-    case AMDILISD::ATOM_L_ADD_NORET:
-    case AMDILISD::ATOM_L_AND_NORET:
-    case AMDILISD::ATOM_L_MAX_NORET:
-    case AMDILISD::ATOM_L_UMAX_NORET:
-    case AMDILISD::ATOM_L_MIN_NORET:
-    case AMDILISD::ATOM_L_UMIN_NORET:
-    case AMDILISD::ATOM_L_OR_NORET:
-    case AMDILISD::ATOM_L_SUB_NORET:
-    case AMDILISD::ATOM_L_RSUB_NORET:
-    case AMDILISD::ATOM_L_XCHG_NORET:
-    case AMDILISD::ATOM_L_XOR_NORET:
-    case AMDILISD::ATOM_R_ADD:
-    case AMDILISD::ATOM_R_AND:
-    case AMDILISD::ATOM_R_MAX:
-    case AMDILISD::ATOM_R_UMAX:
-    case AMDILISD::ATOM_R_MIN:
-    case AMDILISD::ATOM_R_UMIN:
-    case AMDILISD::ATOM_R_OR:
-    case AMDILISD::ATOM_R_SUB:
-    case AMDILISD::ATOM_R_RSUB:
-    case AMDILISD::ATOM_R_XCHG:
-    case AMDILISD::ATOM_R_XOR:
-    case AMDILISD::ATOM_R_ADD_NORET:
-    case AMDILISD::ATOM_R_AND_NORET:
-    case AMDILISD::ATOM_R_MAX_NORET:
-    case AMDILISD::ATOM_R_UMAX_NORET:
-    case AMDILISD::ATOM_R_MIN_NORET:
-    case AMDILISD::ATOM_R_UMIN_NORET:
-    case AMDILISD::ATOM_R_OR_NORET:
-    case AMDILISD::ATOM_R_SUB_NORET:
-    case AMDILISD::ATOM_R_RSUB_NORET:
-    case AMDILISD::ATOM_R_XCHG_NORET:
-    case AMDILISD::ATOM_R_XOR_NORET:
-    case AMDILISD::ATOM_G_CMPXCHG:
-    case AMDILISD::ATOM_G_CMPXCHG_NORET:
-    case AMDILISD::ATOM_L_CMPXCHG:
-    case AMDILISD::ATOM_L_CMPXCHG_NORET:
-    case AMDILISD::ATOM_R_CMPXCHG:
-    case AMDILISD::ATOM_R_CMPXCHG_NORET:
-             break;
-    case AMDILISD::ATOM_G_DEC:
-             addOne = true;
-             if (Subtarget.calVersion() >= CAL_VERSION_SC_136) {
-               addVal = (uint32_t)-1;
-             } else {
-               opc = AMDILISD::ATOM_G_SUB;
-             }
-             break;
-    case AMDILISD::ATOM_G_INC:
-             addOne = true;
-             if (Subtarget.calVersion() >= CAL_VERSION_SC_136) {
-               addVal = (uint32_t)-1;
-             } else {
-               opc = AMDILISD::ATOM_G_ADD;
-             }
-             break;
-    case AMDILISD::ATOM_G_DEC_NORET:
-             addOne = true;
-             if (Subtarget.calVersion() >= CAL_VERSION_SC_136) {
-               addVal = (uint32_t)-1;
-             } else {
-               opc = AMDILISD::ATOM_G_SUB_NORET;
-             }
-             break;
-    case AMDILISD::ATOM_G_INC_NORET:
-             addOne = true;
-             if (Subtarget.calVersion() >= CAL_VERSION_SC_136) {
-               addVal = (uint32_t)-1;
-             } else {
-               opc = AMDILISD::ATOM_G_ADD_NORET;
-             }
-             break;
-    case AMDILISD::ATOM_L_DEC:
-             addOne = true;
-             if (Subtarget.calVersion() >= CAL_VERSION_SC_136) {
-               addVal = (uint32_t)-1;
-             } else {
-               opc = AMDILISD::ATOM_L_SUB;
-             }
-             break;
-    case AMDILISD::ATOM_L_INC:
-             addOne = true;
-             if (Subtarget.calVersion() >= CAL_VERSION_SC_136) {
-               addVal = (uint32_t)-1;
-             } else {
-               opc = AMDILISD::ATOM_L_ADD;
-             }
-             break;
-    case AMDILISD::ATOM_L_DEC_NORET:
-             addOne = true;
-             if (Subtarget.calVersion() >= CAL_VERSION_SC_136) {
-               addVal = (uint32_t)-1;
-             } else {
-               opc = AMDILISD::ATOM_L_SUB_NORET;
-             }
-             break;
-    case AMDILISD::ATOM_L_INC_NORET:
-             addOne = true;
-             if (Subtarget.calVersion() >= CAL_VERSION_SC_136) {
-               addVal = (uint32_t)-1;
-             } else {
-               opc = AMDILISD::ATOM_L_ADD_NORET;
-             }
-             break;
-    case AMDILISD::ATOM_R_DEC:
-             addOne = true;
-             if (Subtarget.calVersion() >= CAL_VERSION_SC_136) {
-               addVal = (uint32_t)-1;
-             } else {
-               opc = AMDILISD::ATOM_R_SUB;
-             }
-             break;
-    case AMDILISD::ATOM_R_INC:
-             addOne = true;
-             if (Subtarget.calVersion() >= CAL_VERSION_SC_136) {
-               addVal = (uint32_t)-1;
-             } else {
-               opc = AMDILISD::ATOM_R_ADD;
-             }
-             break;
-    case AMDILISD::ATOM_R_DEC_NORET:
-             addOne = true;
-             if (Subtarget.calVersion() >= CAL_VERSION_SC_136) {
-               addVal = (uint32_t)-1;
-             } else {
-               opc = AMDILISD::ATOM_R_SUB;
-             }
-             break;
-    case AMDILISD::ATOM_R_INC_NORET:
-             addOne = true;
-             if (Subtarget.calVersion() >= CAL_VERSION_SC_136) {
-               addVal = (uint32_t)-1;
-             } else {
-               opc = AMDILISD::ATOM_R_ADD_NORET;
-             }
-             break;
+#ifdef DEBUGTMP
+#undef INT64_C
+#endif
+#undef DEBUGTMP
+
+///==== AMDGPU Functions ====///
+
+bool AMDILDAGToDAGISel::SelectADDR8BitOffset(SDValue Addr, SDValue& Base,
+                                             SDValue& Offset) {
+  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
+      Addr.getOpcode() == ISD::TargetGlobalAddress) {
+    return false;
   }
-  // The largest we can have is a cmpxchg w/ a return value and an output chain.
-  // The cmpxchg function has 3 inputs and a single output along with an
-  // output change and a target constant, giving a total of 6.
-  SDValue Ops[12];
-  unsigned x = 0;
-  unsigned y = N->getNumOperands();
-  for (x = 0; x < y; ++x) {
-    Ops[x] = N->getOperand(x);
+
+
+  if (Addr.getOpcode() == ISD::ADD) {
+    bool Match = false;
+
+    // Find the base ptr and the offset
+    for (unsigned i = 0; i < Addr.getNumOperands(); i++) {
+      SDValue Arg = Addr.getOperand(i);
+      ConstantSDNode * OffsetNode = dyn_cast<ConstantSDNode>(Arg);
+      // This arg isn't a constant so it must be the base PTR.
+      if (!OffsetNode) {
+        Base = Addr.getOperand(i);
+        continue;
+      }
+      // Check if the constant argument fits in 8-bits.  The offset is in bytes
+      // so we need to convert it to dwords.
+      if (isInt<8>(OffsetNode->getZExtValue() >> 2)) {
+        Match = true;
+        Offset = CurDAG->getTargetConstant(OffsetNode->getZExtValue() >> 2,
+                                           MVT::i32);
+      }
+    }
+    return Match;
   }
-  if (addOne) {
-    Ops[x++] = SDValue(SelectCode(CurDAG->getConstant(addVal, MVT::i32).getNode()), 0);
+
+  // Default case, no offset
+  Base = Addr;
+  Offset = CurDAG->getTargetConstant(0, MVT::i32);
+  return true;
+}
+
+bool AMDILDAGToDAGISel::SelectADDRVTX_READ(SDValue Addr, SDValue &Base,
+                                           SDValue &Offset)
+{
+  ConstantSDNode * IMMOffset;
+
+  if (Addr.getOpcode() == ISD::ADD
+      && (IMMOffset = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
+      && isInt<16>(IMMOffset->getZExtValue())) {
+
+      Base = Addr.getOperand(0);
+      Offset = CurDAG->getTargetConstant(IMMOffset->getZExtValue(), MVT::i32);
+      return true;
+  // If the pointer address is constant, we can move it to the offset field.
+  } else if ((IMMOffset = dyn_cast<ConstantSDNode>(Addr))
+             && isInt<16>(IMMOffset->getZExtValue())) {
+    Base = CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
+                                  CurDAG->getEntryNode().getDebugLoc(),
+                                  AMDGPU::ZERO, MVT::i32);
+    Offset = CurDAG->getTargetConstant(IMMOffset->getZExtValue(), MVT::i32);
+    return true;
   }
-  Ops[x++] = CurDAG->getTargetConstant(0, MVT::i32);
-  SDVTList Tys = N->getVTList();
-  MemSDNode *MemNode = dyn_cast<MemSDNode>(N);
-  assert(MemNode && "Atomic should be of MemSDNode type!");
-  N = CurDAG->getMemIntrinsicNode(opc, N->getDebugLoc(), Tys, Ops, x,
-      MemNode->getMemoryVT(), MemNode->getMemOperand()).getNode();
-  return N;
+
+  // Default case, no offset
+  Base = Addr;
+  Offset = CurDAG->getTargetConstant(0, MVT::i32);
+  return true;
 }
 
-#ifdef DEBUGTMP
-#undef INT64_C
-#endif
-#undef DEBUGTMP
+bool AMDILDAGToDAGISel::SelectADDRReg(SDValue Addr, SDValue& Base,
+                                      SDValue& Offset) {
+  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
+      Addr.getOpcode() == ISD::TargetGlobalAddress  ||
+      Addr.getOpcode() != ISD::ADD) {
+    return false;
+  }
+
+  Base = Addr.getOperand(0);
+  Offset = Addr.getOperand(1);
+
+  return false;
+}