CellSPU:
- Fix bugs 3194, 3195: i128 load/stores produce correct code (although, we
  need to ensure that i128 is 16-byte aligned in real life), and 128 zero-
  extends are supported.
- New td file: SPU128InstrInfo.td: this is where all new i128 support should
  be put in the future.
- Continue to hammer on i64 operations and test cases; ensure that the only
  remaining problem will be i64 mul.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@61784 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/CellSPU/SPUISelLowering.cpp b/lib/Target/CellSPU/SPUISelLowering.cpp
index c13d696..7e63a87 100644
--- a/lib/Target/CellSPU/SPUISelLowering.cpp
+++ b/lib/Target/CellSPU/SPUISelLowering.cpp
@@ -114,7 +114,7 @@
   setOperationAction(ISD::ConstantFP, MVT::f64, Custom);
 
   // SPU's loads and stores have to be custom lowered:
-  for (unsigned sctype = (unsigned) MVT::i8; sctype < (unsigned) MVT::f128;
+  for (unsigned sctype = (unsigned) MVT::i8; sctype < (unsigned) MVT::i128;
        ++sctype) {
     MVT VT = (MVT::SimpleValueType)sctype;
 
@@ -947,6 +947,9 @@
       case MVT::i64:
         ArgRegClass = &SPU::R64CRegClass;
         break;
+      case MVT::i128:
+        ArgRegClass = &SPU::GPRCRegClass;
+        break;
       case MVT::f32:
         ArgRegClass = &SPU::R32FPRegClass;
         break;
@@ -1070,6 +1073,8 @@
 
     switch (Arg.getValueType().getSimpleVT()) {
     default: assert(0 && "Unexpected ValueType for argument!");
+    case MVT::i8:
+    case MVT::i16:
     case MVT::i32:
     case MVT::i64:
     case MVT::i128:
@@ -1220,6 +1225,11 @@
     ResultVals[0] = Chain.getValue(0);
     NumResults = 1;
     break;
+  case MVT::i128:
+    Chain = DAG.getCopyFromReg(Chain, SPU::R3, MVT::i128, InFlag).getValue(1);
+    ResultVals[0] = Chain.getValue(0);
+    NumResults = 1;
+    break;
   case MVT::f32:
   case MVT::f64:
     Chain = DAG.getCopyFromReg(Chain, SPU::R3, TheCall->getValueType(0),
@@ -2182,24 +2192,48 @@
     MVT Op0VT = Op0.getValueType();
     MVT Op0VecVT = MVT::getVectorVT(Op0VT, (128 / Op0VT.getSizeInBits()));
 
-    assert(Op0VT == MVT::i32
-           && "CellSPU: Zero/sign extending something other than i32");
-
-    DEBUG(cerr << "CellSPU.LowerI64Math: lowering zero/sign/any extend\n");
-
     SDValue PromoteScalar =
             DAG.getNode(SPUISD::PREFSLOT2VEC, Op0VecVT, Op0);
 
     // Use a shuffle to zero extend the i32 to i64 directly:
-    SDValue shufMask = DAG.getNode(ISD::BUILD_VECTOR, Op0VecVT,
-        DAG.getConstant(0x80808080, MVT::i32), DAG.getConstant(0x00010203,
-            MVT::i32), DAG.getConstant(0x80808080, MVT::i32), DAG.getConstant(
-            0x08090a0b, MVT::i32));
-    SDValue zextShuffle = DAG.getNode(SPUISD::SHUFB, Op0VecVT, PromoteScalar,
-        PromoteScalar, shufMask);
+    SDValue shufMask;
 
-    return DAG.getNode(SPUISD::VEC2PREFSLOT, VT, DAG.getNode(ISD::BIT_CONVERT,
-        VecVT, zextShuffle));
+    switch (Op0VT.getSimpleVT()) {
+    default:
+      cerr << "CellSPU LowerI64Math: Unhandled zero/any extend MVT\n";
+      abort();
+      /*NOTREACHED*/
+      break;
+    case MVT::i32:
+      shufMask = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
+                             DAG.getConstant(0x80808080, MVT::i32),
+                             DAG.getConstant(0x00010203, MVT::i32),
+                             DAG.getConstant(0x80808080, MVT::i32),
+                             DAG.getConstant(0x08090a0b, MVT::i32));
+        break;
+
+    case MVT::i16:
+      shufMask = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
+                             DAG.getConstant(0x80808080, MVT::i32),
+                             DAG.getConstant(0x80800203, MVT::i32),
+                             DAG.getConstant(0x80808080, MVT::i32),
+                             DAG.getConstant(0x80800a0b, MVT::i32));
+      break;
+
+    case MVT::i8:
+      shufMask = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
+                             DAG.getConstant(0x80808080, MVT::i32),
+                             DAG.getConstant(0x80808003, MVT::i32),
+                             DAG.getConstant(0x80808080, MVT::i32),
+                             DAG.getConstant(0x8080800b, MVT::i32));
+      break;
+    }
+
+    SDValue zextShuffle = DAG.getNode(SPUISD::SHUFB, Op0VecVT,
+                                      PromoteScalar, PromoteScalar, shufMask);
+
+    return DAG.getNode(SPUISD::VEC2PREFSLOT, VT,
+                       DAG.getNode(ISD::BIT_CONVERT, VecVT, zextShuffle));
   }
 
   case ISD::ADD: {