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: {