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/Main.cpp b/src/Reactor/Main.cpp
index 558110d..3adb638 100644
--- a/src/Reactor/Main.cpp
+++ b/src/Reactor/Main.cpp
@@ -182,6 +182,49 @@
 	delete routine;
 }
 
+TEST(SubzeroReactorTest, Concatenate)
+{
+	Routine *routine = nullptr;
+
+	{
+		Function<Int(Pointer<Byte>)> function;
+		{
+			Pointer<Byte> out = function.Arg<0>();
+
+			*Pointer<Int4>(out + 16 * 0)   = Int4(Int2(0x04030201, 0x08070605), Int2(0x0C0B0A09, 0x100F0E0D));
+			*Pointer<Short8>(out + 16 * 1) = Short8(Short4(0x0201, 0x0403, 0x0605, 0x0807), Short4(0x0A09, 0x0C0B, 0x0E0D, 0x100F));
+
+			Return(0);
+		}
+
+		routine = function(L"one");
+
+		if(routine)
+		{
+			int8_t ref[16 * 5] = {1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15, 16,
+			                      1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15, 16};
+
+			int8_t out[16 * 5] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+			                      -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
+		
+			int (*callable)(void*) = (int(*)(void*))routine->getEntry();
+			callable(out);
+
+			for(int row = 0; row < 2; row++)
+			{
+				for(int col = 0; col < 16; col++)
+				{
+					int i = row * 16 + col;
+
+					EXPECT_EQ(out[i], ref[i]) << "Row " << row << " column " << col << " not equal to reference.";
+				}
+			}
+		}
+	}
+
+	delete routine;
+}
+
 TEST(SubzeroReactorTest, Swizzle)
 {
 	Routine *routine = nullptr;
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)