Update the .cvs files.
[oota-llvm.git] / lib / Target / CellSPU / SPUISelDAGToDAG.cpp
index 488c4e526b48698f0630fa5795697ed1e948b28b..d0261fd5a7d7d7cf3ebad56505686e032ddbf427 100644 (file)
 #include "SPUISelLowering.h"
 #include "SPUHazardRecognizers.h"
 #include "SPUFrameInfo.h"
+#include "SPURegisterNames.h"
 #include "llvm/CodeGen/MachineConstantPool.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/MachineModuleInfo.h"
 #include "llvm/CodeGen/SelectionDAG.h"
 #include "llvm/CodeGen/SelectionDAGISel.h"
 #include "llvm/Target/TargetOptions.h"
@@ -31,7 +31,6 @@
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/Compiler.h"
-#include <iostream>
 #include <queue>
 #include <set>
 
@@ -42,14 +41,14 @@ namespace {
   bool
   isI64IntS10Immediate(ConstantSDNode *CN)
   {
-    return isS10Constant(CN->getValue());
+    return isS10Constant(CN->getSignExtended());
   }
 
   //! ConstantSDNode predicate for i32 sign-extended, 10-bit immediates
   bool
   isI32IntS10Immediate(ConstantSDNode *CN)
   {
-    return isS10Constant((int) CN->getValue());
+    return isS10Constant(CN->getSignExtended());
   }
 
 #if 0
@@ -66,14 +65,14 @@ namespace {
   bool
   isI32IntU10Immediate(ConstantSDNode *CN)
   {
-    return isU10Constant((int) CN->getValue());
+    return isU10Constant(CN->getSignExtended());
   }
 
   //! ConstantSDNode predicate for i16 sign-extended, 10-bit immediate values
   bool
   isI16IntS10Immediate(ConstantSDNode *CN)
   {
-    return isS10Constant((short) CN->getValue());
+    return isS10Constant(CN->getSignExtended());
   }
 
   //! SDNode predicate for i16 sign-extended, 10-bit immediate values
@@ -111,9 +110,9 @@ namespace {
   bool
   isIntS16Immediate(ConstantSDNode *CN, short &Imm)
   {
-    MVT::ValueType vt = CN->getValueType(0);
+    MVT vt = CN->getValueType(0);
     Imm = (short) CN->getValue();
-    if (vt >= MVT::i1 && vt <= MVT::i16) {
+    if (vt.getSimpleVT() >= MVT::i1 && vt.getSimpleVT() <= MVT::i16) {
       return true;
     } else if (vt == MVT::i32) {
       int32_t i_val = (int32_t) CN->getValue();
@@ -140,7 +139,7 @@ namespace {
   static bool
   isFPS16Immediate(ConstantFPSDNode *FPN, short &Imm)
   {
-    MVT::ValueType vt = FPN->getValueType(0);
+    MVT vt = FPN->getValueType(0);
     if (vt == MVT::f32) {
       int val = FloatToBits(FPN->getValueAPF().convertToFloat());
       int sval = (int) ((val << 16) >> 16);
@@ -162,34 +161,35 @@ namespace {
   }
 
   //===------------------------------------------------------------------===//
-  //! MVT::ValueType to "useful stuff" mapping structure:
+  //! MVT to "useful stuff" mapping structure:
 
   struct valtype_map_s {
-    MVT::ValueType VT;
+    MVT VT;
     unsigned ldresult_ins;      /// LDRESULT instruction (0 = undefined)
+    bool ldresult_imm;          /// LDRESULT instruction requires immediate?
     int prefslot_byte;          /// Byte offset of the "preferred" slot
   };
 
   const valtype_map_s valtype_map[] = {
-    { MVT::i1,    0,            3 },
-    { MVT::i8,    SPU::ORBIr8,  3 },
-    { MVT::i16,   SPU::ORHIr16, 2 },
-    { MVT::i32,   SPU::ORIr32,  0 },
-    { MVT::i64,   SPU::ORIr64,  0 },
-    { MVT::f32,   0,            0 },
-    { MVT::f64,   0,            0 },
+    { MVT::i1,    0,            false, 3 },
+    { MVT::i8,    SPU::ORBIr8,  true,  3 },
+    { MVT::i16,   SPU::ORHIr16, true,  2 },
+    { MVT::i32,   SPU::ORIr32,  true,  0 },
+    { MVT::i64,   SPU::ORr64,   false, 0 },
+    { MVT::f32,   SPU::ORf32,   false, 0 },
+    { MVT::f64,   SPU::ORf64,   false, 0 },
     // vector types... (sigh!)
-    { MVT::v16i8, 0,            0 },
-    { MVT::v8i16, 0,            0 },
-    { MVT::v4i32, 0,            0 },
-    { MVT::v2i64, 0,            0 },
-    { MVT::v4f32, 0,            0 },
-    { MVT::v2f64, 0,            0 }
+    { MVT::v16i8, 0,            false, 0 },
+    { MVT::v8i16, 0,            false, 0 },
+    { MVT::v4i32, 0,            false, 0 },
+    { MVT::v2i64, 0,            false, 0 },
+    { MVT::v4f32, 0,            false, 0 },
+    { MVT::v2f64, 0,            false, 0 }
   };
 
   const size_t n_valtype_map = sizeof(valtype_map) / sizeof(valtype_map[0]);
 
-  const valtype_map_s *getValueTypeMapEntry(MVT::ValueType VT)
+  const valtype_map_s *getValueTypeMapEntry(MVT VT)
   {
     const valtype_map_s *retval = 0;
     for (size_t i = 0; i < n_valtype_map; ++i) {
@@ -203,7 +203,7 @@ namespace {
 #ifndef NDEBUG
     if (retval == 0) {
       cerr << "SPUISelDAGToDAG.cpp: getValueTypeMapEntry returns NULL for "
-           << MVT::getValueTypeString(VT)
+           << VT.getMVTString()
            << "\n";
       abort();
     }
@@ -213,6 +213,8 @@ namespace {
   }
 }
 
+namespace {
+
 //===--------------------------------------------------------------------===//
 /// SPUDAGToDAGISel - Cell SPU-specific code to select SPU machine
 /// instructions for SelectionDAG operations.
@@ -335,6 +337,8 @@ public:
 #include "SPUGenDAGISel.inc"
 };
 
+}
+
 /// InstructionSelectBasicBlock - This callback is invoked by
 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
 void
@@ -360,7 +364,7 @@ bool
 SPUDAGToDAGISel::SelectAFormAddr(SDOperand Op, SDOperand N, SDOperand &Base,
                     SDOperand &Index) {
   // These match the addr256k operand type:
-  MVT::ValueType OffsVT = MVT::i16;
+  MVT OffsVT = MVT::i16;
   SDOperand Zero = CurDAG->getTargetConstant(0, OffsVT);
 
   switch (N.getOpcode()) {
@@ -411,7 +415,10 @@ SPUDAGToDAGISel::SelectAFormAddr(SDOperand Op, SDOperand N, SDOperand &Base,
 bool 
 SPUDAGToDAGISel::SelectDForm2Addr(SDOperand Op, SDOperand N, SDOperand &Disp,
                                   SDOperand &Base) {
-  return DFormAddressPredicate(Op, N, Disp, Base, -(1 << 7), (1 << 7) - 1);
+  const int minDForm2Offset = -(1 << 7);
+  const int maxDForm2Offset = (1 << 7) - 1;
+  return DFormAddressPredicate(Op, N, Disp, Base, minDForm2Offset,
+                               maxDForm2Offset);
 }
 
 /*!
@@ -439,16 +446,17 @@ SPUDAGToDAGISel::DFormAddressPredicate(SDOperand Op, SDOperand N, SDOperand &Bas
                                       SDOperand &Index, int minOffset,
                                       int maxOffset) {
   unsigned Opc = N.getOpcode();
-  unsigned PtrTy = SPUtli.getPointerTy();
+  MVT PtrTy = SPUtli.getPointerTy();
 
   if (Opc == ISD::FrameIndex) {
     // Stack frame index must be less than 512 (divided by 16):
-    FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N);
+    FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(N);
+    int FI = int(FIN->getIndex());
     DEBUG(cerr << "SelectDFormAddr: ISD::FrameIndex = "
-          << FI->getIndex() << "\n");
-    if (FI->getIndex() < maxOffset) {
+               << FI << "\n");
+    if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) {
       Base = CurDAG->getTargetConstant(0, PtrTy);
-      Index = CurDAG->getTargetFrameIndex(FI->getIndex(), PtrTy);
+      Index = CurDAG->getTargetFrameIndex(FI, PtrTy);
       return true;
     }
   } else if (Opc == ISD::ADD) {
@@ -467,13 +475,14 @@ SPUDAGToDAGISel::DFormAddressPredicate(SDOperand Op, SDOperand N, SDOperand &Bas
       int32_t offset = int32_t(CN->getSignExtended());
 
       if (Op0.getOpcode() == ISD::FrameIndex) {
-        FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Op0);
+        FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Op0);
+        int FI = int(FIN->getIndex());
         DEBUG(cerr << "SelectDFormAddr: ISD::ADD offset = " << offset
-              << " frame index = " << FI->getIndex() << "\n");
+                   << " frame index = " << FI << "\n");
 
-        if (FI->getIndex() < maxOffset) {
+        if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) {
           Base = CurDAG->getTargetConstant(offset, PtrTy);
-          Index = CurDAG->getTargetFrameIndex(FI->getIndex(), PtrTy);
+          Index = CurDAG->getTargetFrameIndex(FI, PtrTy);
           return true;
         }
       } else if (offset > minOffset && offset < maxOffset) {
@@ -487,13 +496,14 @@ SPUDAGToDAGISel::DFormAddressPredicate(SDOperand Op, SDOperand N, SDOperand &Bas
       int32_t offset = int32_t(CN->getSignExtended());
 
       if (Op1.getOpcode() == ISD::FrameIndex) {
-        FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Op1);
+        FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Op1);
+        int FI = int(FIN->getIndex());
         DEBUG(cerr << "SelectDFormAddr: ISD::ADD offset = " << offset
-              << " frame index = " << FI->getIndex() << "\n");
+                   << " frame index = " << FI << "\n");
 
-        if (FI->getIndex() < maxOffset) {
+        if (SPUFrameInfo::FItoStackOffset(FI) < maxOffset) {
           Base = CurDAG->getTargetConstant(offset, PtrTy);
-          Index = CurDAG->getTargetFrameIndex(FI->getIndex(), PtrTy);
+          Index = CurDAG->getTargetFrameIndex(FI, PtrTy);
           return true;
         }
       } else if (offset > minOffset && offset < maxOffset) {
@@ -577,23 +587,37 @@ SPUDAGToDAGISel::Select(SDOperand Op) {
   unsigned Opc = N->getOpcode();
   int n_ops = -1;
   unsigned NewOpc;
-  MVT::ValueType OpVT = Op.getValueType();
+  MVT OpVT = Op.getValueType();
   SDOperand Ops[8];
 
   if (Opc >= ISD::BUILTIN_OP_END && Opc < SPUISD::FIRST_NUMBER) {
     return NULL;   // Already selected.
   } else if (Opc == ISD::FrameIndex) {
-    // Selects to AIr32 FI, 0 which in turn will become AIr32 SP, imm.
-    int FI = cast<FrameIndexSDNode>(N)->getIndex();
-    MVT::ValueType PtrVT = SPUtli.getPointerTy();
-    SDOperand Zero = CurDAG->getTargetConstant(0, PtrVT);
-    SDOperand TFI = CurDAG->getTargetFrameIndex(FI, PtrVT);
-
-    DEBUG(cerr << "SPUDAGToDAGISel: Replacing FrameIndex with AI32 <FI>, 0\n");
-    NewOpc = SPU::AIr32;
-    Ops[0] = TFI;
-    Ops[1] = Zero;
-    n_ops = 2;
+    // Selects to (add $sp, FI * stackSlotSize)
+    int FI =
+      SPUFrameInfo::FItoStackOffset(cast<FrameIndexSDNode>(N)->getIndex());
+    MVT PtrVT = SPUtli.getPointerTy();
+
+    // Adjust stack slot to actual offset in frame:
+    if (isS10Constant(FI)) {
+      DEBUG(cerr << "SPUDAGToDAGISel: Replacing FrameIndex with AIr32 $sp, "
+                 << FI
+                 << "\n");
+      NewOpc = SPU::AIr32;
+      Ops[0] = CurDAG->getRegister(SPU::R1, PtrVT);
+      Ops[1] = CurDAG->getTargetConstant(FI, PtrVT);
+      n_ops = 2;
+    } else {
+      DEBUG(cerr << "SPUDAGToDAGISel: Replacing FrameIndex with Ar32 $sp, "
+                 << FI
+                 << "\n");
+      NewOpc = SPU::Ar32;
+      Ops[0] = CurDAG->getRegister(SPU::R1, PtrVT);
+      Ops[1] = CurDAG->getConstant(FI, PtrVT);
+      n_ops = 2;
+
+      AddToISelQueue(Ops[1]);
+    }
   } else if (Opc == ISD::ZERO_EXTEND) {
     // (zero_extend:i16 (and:i8 <arg>, <const>))
     const SDOperand &Op1 = N->getOperand(0);
@@ -604,7 +628,7 @@ SPUDAGToDAGISel::Select(SDOperand Op) {
         // to i8, then i8 to i16 in logical/branching operations.
         DEBUG(cerr << "CellSPU: Coalescing (zero_extend:i16 (and:i8 "
                       "<arg>, <const>))\n");
-        NewOpc = SPU::ANDHI1To2;
+        NewOpc = SPU::ANDHIi8i16;
         Ops[0] = Op1.getOperand(0);
         Ops[1] = Op1.getOperand(1);
         n_ops = 2;
@@ -612,28 +636,27 @@ SPUDAGToDAGISel::Select(SDOperand Op) {
     }
   } else if (Opc == SPUISD::LDRESULT) {
     // Custom select instructions for LDRESULT
-    unsigned VT = N->getValueType(0);
+    MVT VT = N->getValueType(0);
     SDOperand Arg = N->getOperand(0);
     SDOperand Chain = N->getOperand(1);
     SDNode *Result;
+    const valtype_map_s *vtm = getValueTypeMapEntry(VT);
+
+    if (vtm->ldresult_ins == 0) {
+      cerr << "LDRESULT for unsupported type: "
+           << VT.getMVTString()
+           << "\n";
+      abort();
+    }
 
     AddToISelQueue(Arg);
-    if (!MVT::isFloatingPoint(VT)) {
+    Opc = vtm->ldresult_ins;
+    if (vtm->ldresult_imm) {
       SDOperand Zero = CurDAG->getTargetConstant(0, VT);
-      const valtype_map_s *vtm = getValueTypeMapEntry(VT);
-
-      if (vtm->ldresult_ins == 0) {
-        cerr << "LDRESULT for unsupported type: "
-             << MVT::getValueTypeString(VT)
-             << "\n";
-        abort();
-      } else
-        Opc = vtm->ldresult_ins;
 
       AddToISelQueue(Zero);
       Result = CurDAG->getTargetNode(Opc, VT, MVT::Other, Arg, Zero, Chain);
     } else {
-      Opc = (VT == MVT::f32 ? SPU::ORf32 : SPU::ORf64);
       Result = CurDAG->getTargetNode(Opc, MVT::Other, Arg, Arg, Chain);
     }
 
@@ -647,7 +670,7 @@ SPUDAGToDAGISel::Select(SDOperand Op) {
         /* || Op0.getOpcode() == SPUISD::AFormAddr) */
       // (IndirectAddr (LDRESULT, imm))
       SDOperand Op1 = Op.getOperand(1);
-      MVT::ValueType VT = Op.getValueType();
+      MVT VT = Op.getValueType();
 
       DEBUG(cerr << "CellSPU: IndirectAddr(LDRESULT, imm):\nOp0 = ");
       DEBUG(Op.getOperand(0).Val->dump(CurDAG));