Implement missing vector operations.
Bug swiftshader:15
Change-Id: I2116fa6ad368c801e921becd89259b02b4ca68ce
Reviewed-on: https://swiftshader-review.googlesource.com/8251
Reviewed-by: Nicolas Capens <capn@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Tested-by: Nicolas Capens <capn@google.com>
diff --git a/src/Reactor/SubzeroReactor.cpp b/src/Reactor/SubzeroReactor.cpp
index 973180c..07ea893 100644
--- a/src/Reactor/SubzeroReactor.cpp
+++ b/src/Reactor/SubzeroReactor.cpp
@@ -2904,7 +2904,7 @@
Short2::Short2(RValue<Short4> cast)
{
- assert(false && "UNIMPLEMENTED");
+ storeValue(Nucleus::createBitCast(cast.value, getType()));
}
Type *Short2::getType()
@@ -2914,7 +2914,7 @@
UShort2::UShort2(RValue<UShort4> cast)
{
- assert(false && "UNIMPLEMENTED");
+ storeValue(Nucleus::createBitCast(cast.value, getType()));
}
Type *UShort2::getType()
@@ -3637,7 +3637,10 @@
Short8::Short8(RValue<Short4> lo, RValue<Short4> hi)
{
- assert(false && "UNIMPLEMENTED");
+ int shuffle[8] = {0, 1, 2, 3, 8, 9, 10, 11}; // Real type is v8i16
+ Value *packed = Nucleus::createShuffleVector(lo.value, hi.value, shuffle);
+
+ storeValue(packed);
}
RValue<Short8> operator+(RValue<Short8> lhs, RValue<Short8> rhs)
@@ -3700,7 +3703,10 @@
UShort8::UShort8(RValue<UShort4> lo, RValue<UShort4> hi)
{
- assert(false && "UNIMPLEMENTED");
+ int shuffle[8] = {0, 1, 2, 3, 8, 9, 10, 11}; // Real type is v8i16
+ Value *packed = Nucleus::createShuffleVector(lo.value, hi.value, shuffle);
+
+ storeValue(packed);
}
RValue<UShort8> UShort8::operator=(RValue<UShort8> rhs)
@@ -4230,7 +4236,18 @@
UInt::UInt(RValue<Float> cast)
{
- assert(false && "UNIMPLEMENTED");
+ // Smallest positive value representable in UInt, but not in Int
+ const unsigned int ustart = 0x80000000u;
+ const float ustartf = float(ustart);
+
+ // If the value is negative, store 0, otherwise store the result of the conversion
+ storeValue((~(As<Int>(cast) >> 31) &
+ // Check if the value can be represented as an Int
+ IfThenElse(cast >= ustartf,
+ // If the value is too large, subtract ustart and re-add it after conversion.
+ As<Int>(As<UInt>(Int(cast - Float(ustartf))) + UInt(ustart)),
+ // Otherwise, just convert normally
+ Int(cast))).value);
}
UInt::UInt()
@@ -4731,12 +4748,15 @@
RValue<Short4> UnpackLow(RValue<Int2> x, RValue<Int2> y)
{
- assert(false && "UNIMPLEMENTED"); return RValue<Short4>(V(nullptr));
+ int shuffle[4] = {0, 4, 1, 5}; // Real type is v4i32
+ return As<Short4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
}
RValue<Short4> UnpackHigh(RValue<Int2> x, RValue<Int2> y)
{
- assert(false && "UNIMPLEMENTED"); return RValue<Short4>(V(nullptr));
+ int shuffle[16] = {0, 4, 1, 5}; // Real type is v4i32
+ auto lowHigh = RValue<Int4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
+ return As<Short4>(Swizzle(lowHigh, 0xEE));
}
RValue<Int> Extract(RValue<Int2> val, int i)
@@ -5077,7 +5097,10 @@
Int4::Int4(RValue<Int2> lo, RValue<Int2> hi)
{
- assert(false && "UNIMPLEMENTED");
+ int shuffle[4] = {0, 1, 4, 5}; // Real type is v4i32
+ Value *packed = Nucleus::createShuffleVector(lo.value, hi.value, shuffle);
+
+ storeValue(packed);
}
Int4::Int4(RValue<Int> rhs)
@@ -5369,7 +5392,18 @@
{
// xyzw.parent = this;
- assert(false && "UNIMPLEMENTED");
+ // Smallest positive value representable in UInt, but not in Int
+ const unsigned int ustart = 0x80000000u;
+ const float ustartf = float(ustart);
+
+ // Check if the value can be represented as an Int
+ Int4 uiValue = CmpNLT(cast, Float4(ustartf));
+ // If the value is too large, subtract ustart and re-add it after conversion.
+ uiValue = (uiValue & As<Int4>(As<UInt4>(Int4(cast - Float4(ustartf))) + UInt4(ustart))) |
+ // Otherwise, just convert normally
+ (~uiValue & Int4(cast));
+ // If the value is negative, store 0, otherwise store the result of the conversion
+ storeValue((~(As<Int4>(cast) >> 31) & uiValue).value);
}
UInt4::UInt4()
@@ -5453,7 +5487,10 @@
UInt4::UInt4(RValue<UInt2> lo, RValue<UInt2> hi)
{
- assert(false && "UNIMPLEMENTED");
+ int shuffle[4] = {0, 1, 4, 5}; // Real type is v4i32
+ Value *packed = Nucleus::createShuffleVector(lo.value, hi.value, shuffle);
+
+ storeValue(packed);
}
RValue<UInt4> UInt4::operator=(RValue<UInt4> rhs)