Avoid ambiguous vector casts.

Bug swiftshader:15

Change-Id: Ia42d21b4f2c9e19a839ffb414661f2dffa350692
Reviewed-on: https://swiftshader-review.googlesource.com/7711
Reviewed-by: Nicolas Capens <capn@google.com>
Tested-by: Nicolas Capens <capn@google.com>
Reviewed-on: https://swiftshader-review.googlesource.com/7630
Reviewed-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/Reactor/LLVMReactor.cpp b/src/Reactor/LLVMReactor.cpp
index 8b32d1f..fdc358a 100644
--- a/src/Reactor/LLVMReactor.cpp
+++ b/src/Reactor/LLVMReactor.cpp
@@ -1931,6 +1931,21 @@
 		return T(llvm::Type::getInt16Ty(*::context));
 	}
 
+	Byte4::Byte4(RValue<Byte8> cast)
+	{
+	//	xyzw.parent = this;
+
+		storeValue(Nucleus::createTrunc(Nucleus::createBitCast(cast.value, Long::getType()), Int::getType()));
+	}
+
+	Byte4::Byte4(const Reference<Byte4> &rhs)
+	{
+	//	xyzw.parent = this;
+
+		Value *value = rhs.loadValue();
+		storeValue(value);
+	}
+
 	Type *Byte4::getType()
 	{
 		#if 0
@@ -1972,24 +1987,6 @@
 		storeValue(Nucleus::createBitCast(vector, getType()));
 	}
 
-	Byte8::Byte8(int64_t x)
-	{
-	//	xyzw.parent = this;
-
-		Constant *constantVector[8];
-		constantVector[0] = Nucleus::createConstantByte((unsigned char)(x >>  0));
-		constantVector[1] = Nucleus::createConstantByte((unsigned char)(x >>  8));
-		constantVector[2] = Nucleus::createConstantByte((unsigned char)(x >> 16));
-		constantVector[3] = Nucleus::createConstantByte((unsigned char)(x >> 24));
-		constantVector[4] = Nucleus::createConstantByte((unsigned char)(x >> 32));
-		constantVector[5] = Nucleus::createConstantByte((unsigned char)(x >> 40));
-		constantVector[6] = Nucleus::createConstantByte((unsigned char)(x >> 48));
-		constantVector[7] = Nucleus::createConstantByte((unsigned char)(x >> 56));
-		Value *vector = V(Nucleus::createConstantVector(constantVector, 8));
-
-		storeValue(Nucleus::createBitCast(vector, getType()));
-	}
-
 	Byte8::Byte8(RValue<Byte8> rhs)
 	{
 	//	xyzw.parent = this;
@@ -2185,7 +2182,7 @@
 	{
 		if(CPUID::supportsMMX2())
 		{
-			return val ^ Byte8(0xFFFFFFFFFFFFFFFF);
+			return val ^ Byte8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
 		}
 		else
 		{
@@ -2291,24 +2288,6 @@
 		storeValue(Nucleus::createBitCast(vector, getType()));
 	}
 
-	SByte8::SByte8(int64_t x)
-	{
-	//	xyzw.parent = this;
-
-		Constant *constantVector[8];
-		constantVector[0] = Nucleus::createConstantByte((unsigned char)(x >>  0));
-		constantVector[1] = Nucleus::createConstantByte((unsigned char)(x >>  8));
-		constantVector[2] = Nucleus::createConstantByte((unsigned char)(x >> 16));
-		constantVector[3] = Nucleus::createConstantByte((unsigned char)(x >> 24));
-		constantVector[4] = Nucleus::createConstantByte((unsigned char)(x >> 32));
-		constantVector[5] = Nucleus::createConstantByte((unsigned char)(x >> 40));
-		constantVector[6] = Nucleus::createConstantByte((unsigned char)(x >> 48));
-		constantVector[7] = Nucleus::createConstantByte((unsigned char)(x >> 56));
-		Value *vector = V(Nucleus::createConstantVector(constantVector, 8));
-
-		storeValue(Nucleus::createBitCast(vector, getType()));
-	}
-
 	SByte8::SByte8(RValue<SByte8> rhs)
 	{
 	//	xyzw.parent = this;
@@ -2483,7 +2462,7 @@
 	{
 		if(CPUID::supportsMMX2())
 		{
-			return val ^ SByte8(0xFFFFFFFFFFFFFFFF);
+			return val ^ SByte8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
 		}
 		else
 		{
@@ -2614,6 +2593,34 @@
 		return T( VectorType::get(SByte::getType(), 16));
 	}
 
+	Short2::Short2(RValue<Short4> cast)
+	{
+		storeValue(Nucleus::createTrunc(Nucleus::createBitCast(cast.value, Long::getType()), UInt::getType()));
+	}
+
+	Type *Short2::getType()
+	{
+		#if 0
+			return T(VectorType::get(Short::getType(), 2));
+		#else
+			return UInt::getType();   // FIXME: LLVM doesn't manipulate it as one 32-bit block
+		#endif
+	}
+
+	UShort2::UShort2(RValue<UShort4> cast)
+	{
+		storeValue(Nucleus::createTrunc(Nucleus::createBitCast(cast.value, Long::getType()), UInt::getType()));
+	}
+
+	Type *UShort2::getType()
+	{
+		#if 0
+			return T(VectorType::get(UShort::getType(), 2));
+		#else
+			return UInt::getType();   // FIXME: LLVM doesn't manipulate it as one 32-bit block
+		#endif
+	}
+
 	Short4::Short4(RValue<Int> cast)
 	{
 		Value *extend = Nucleus::createZExt(cast.value, Long::getType());
@@ -3331,6 +3338,42 @@
 		}
 	}
 
+	RValue<UShort4> operator&(RValue<UShort4> lhs, RValue<UShort4> rhs)
+	{
+		if(CPUID::supportsMMX2())
+		{
+			return As<UShort4>(x86::pand(As<Short4>(lhs), As<Short4>(rhs)));
+		}
+		else
+		{
+			return RValue<UShort4>(Nucleus::createAnd(lhs.value, rhs.value));
+		}
+	}
+
+	RValue<UShort4> operator|(RValue<UShort4> lhs, RValue<UShort4> rhs)
+	{
+		if(CPUID::supportsMMX2())
+		{
+			return As<UShort4>(x86::por(As<Short4>(lhs), As<Short4>(rhs)));
+		}
+		else
+		{
+			return RValue<UShort4>(Nucleus::createOr(lhs.value, rhs.value));
+		}
+	}
+
+	RValue<UShort4> operator^(RValue<UShort4> lhs, RValue<UShort4> rhs)
+	{
+		if(CPUID::supportsMMX2())
+		{
+			return As<UShort4>(x86::pxor(As<Short4>(lhs), As<Short4>(rhs)));
+		}
+		else
+		{
+			return RValue<UShort4>(Nucleus::createXor(lhs.value, rhs.value));
+		}
+	}
+
 	RValue<UShort4> operator<<(RValue<UShort4> lhs, unsigned char rhs)
 	{
 	//	return RValue<Short4>(Nucleus::createShl(lhs.value, rhs.value));
diff --git a/src/Reactor/Reactor.hpp b/src/Reactor/Reactor.hpp
index 60cbabc..cbef855 100644
--- a/src/Reactor/Reactor.hpp
+++ b/src/Reactor/Reactor.hpp
@@ -34,6 +34,8 @@
 	class SByte16;
 	class Short;
 	class UShort;
+	class Short2;
+	class UShort2;
 	class Short4;
 	class UShort4;
 	class Short8;
@@ -429,11 +431,13 @@
 	class Byte4 : public Variable<Byte4>
 	{
 	public:
+		explicit Byte4(RValue<Byte8> cast);
+
 	//	Byte4();
 	//	Byte4(int x, int y, int z, int w);
 	//	Byte4(RValue<Byte4> rhs);
 	//	Byte4(const Byte4 &rhs);
-	//	Byte4(const Reference<Byte4> &rhs);
+		Byte4(const Reference<Byte4> &rhs);
 
 	//	RValue<Byte4> operator=(RValue<Byte4> rhs) const;
 	//	RValue<Byte4> operator=(const Byte4 &rhs) const;
@@ -519,7 +523,6 @@
 	public:
 		Byte8();
 		Byte8(uint8_t x0, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4, uint8_t x5, uint8_t x6, uint8_t x7);
-		Byte8(int64_t x);
 		Byte8(RValue<Byte8> rhs);
 		Byte8(const Byte8 &rhs);
 		Byte8(const Reference<Byte8> &rhs);
@@ -573,7 +576,6 @@
 	public:
 		SByte8();
 		SByte8(uint8_t x0, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4, uint8_t x5, uint8_t x6, uint8_t x7);
-		SByte8(int64_t x);
 		SByte8(RValue<SByte8> rhs);
 		SByte8(const SByte8 &rhs);
 		SByte8(const Reference<SByte8> &rhs);
@@ -709,6 +711,22 @@
 //	RValue<SByte16> operator--(const SByte16 &val, int);   // Post-decrement
 //	const SByte16 &operator--(const SByte16 &val);   // Pre-decrement
 
+	class Short2 : public Variable<Short2>
+	{
+	public:
+		explicit Short2(RValue<Short4> cast);
+
+		static Type *getType();
+	};
+
+	class UShort2 : public Variable<UShort2>
+	{
+	public:
+		explicit UShort2(RValue<UShort4> cast);
+
+		static Type *getType();
+	};
+
 	class Short4 : public Variable<Short4>
 	{
 	public:
@@ -822,9 +840,9 @@
 	RValue<UShort4> operator*(RValue<UShort4> lhs, RValue<UShort4> rhs);
 //	RValue<UShort4> operator/(RValue<UShort4> lhs, RValue<UShort4> rhs);
 //	RValue<UShort4> operator%(RValue<UShort4> lhs, RValue<UShort4> rhs);
-//	RValue<UShort4> operator&(RValue<UShort4> lhs, RValue<UShort4> rhs);
-//	RValue<UShort4> operator|(RValue<UShort4> lhs, RValue<UShort4> rhs);
-//	RValue<UShort4> operator^(RValue<UShort4> lhs, RValue<UShort4> rhs);
+	RValue<UShort4> operator&(RValue<UShort4> lhs, RValue<UShort4> rhs);
+	RValue<UShort4> operator|(RValue<UShort4> lhs, RValue<UShort4> rhs);
+	RValue<UShort4> operator^(RValue<UShort4> lhs, RValue<UShort4> rhs);
 	RValue<UShort4> operator<<(RValue<UShort4> lhs, unsigned char rhs);
 	RValue<UShort4> operator>>(RValue<UShort4> lhs, unsigned char rhs);
 	RValue<UShort4> operator<<(RValue<UShort4> lhs, RValue<Long1> rhs);
diff --git a/src/Reactor/SubzeroReactor.cpp b/src/Reactor/SubzeroReactor.cpp
index ae7ad53..c0778af 100644
--- a/src/Reactor/SubzeroReactor.cpp
+++ b/src/Reactor/SubzeroReactor.cpp
@@ -1939,22 +1939,28 @@
 		assert(false && "UNIMPLEMENTED"); return nullptr;
 	}
 
+	Byte4::Byte4(RValue<Byte8> cast)
+	{
+	//	xyzw.parent = this;
+
+		storeValue(Nucleus::createBitCast(cast.value, getType()));
+	}
+
+	Byte4::Byte4(const Reference<Byte4> &rhs)
+	{
+	//	xyzw.parent = this;
+
+		assert(false && "UNIMPLEMENTED");
+	}
+
 	Type *Byte4::getType()
 	{
-		#if 0
-			return VectorType::get(Byte::getType(), 4);
-		#else
-			return UInt::getType();   // FIXME
-		#endif
+		assert(false && "UNIMPLEMENTED"); return nullptr;
 	}
 
 	Type *SByte4::getType()
 	{
-		#if 0
-			return VectorType::get(SByte::getType(), 4);
-		#else
-			return Int::getType();   // FIXME
-		#endif
+		assert(false && "UNIMPLEMENTED"); return nullptr;
 	}
 
 	Byte8::Byte8()
@@ -1965,11 +1971,8 @@
 	Byte8::Byte8(uint8_t x0, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4, uint8_t x5, uint8_t x6, uint8_t x7)
 	{
 	//	xyzw.parent = this;
-	}
 
-	Byte8::Byte8(int64_t x)
-	{
-	//	xyzw.parent = this;
+		assert(false && "UNIMPLEMENTED");
 	}
 
 	Byte8::Byte8(RValue<Byte8> rhs)
@@ -2190,13 +2193,6 @@
 		assert(false && "UNIMPLEMENTED");
 	}
 
-	SByte8::SByte8(int64_t x)
-	{
-	//	xyzw.parent = this;
-
-		assert(false && "UNIMPLEMENTED");
-	}
-
 	SByte8::SByte8(RValue<SByte8> rhs)
 	{
 	//	xyzw.parent = this;
@@ -2454,6 +2450,26 @@
 		assert(false && "UNIMPLEMENTED"); return nullptr;
 	}
 
+	Short2::Short2(RValue<Short4> cast)
+	{
+		assert(false && "UNIMPLEMENTED");
+	}
+
+	Type *Short2::getType()
+	{
+		assert(false && "UNIMPLEMENTED"); return nullptr;
+	}
+
+	UShort2::UShort2(RValue<UShort4> cast)
+	{
+		assert(false && "UNIMPLEMENTED");
+	}
+
+	Type *UShort2::getType()
+	{
+		assert(false && "UNIMPLEMENTED"); return nullptr;
+	}
+
 	Short4::Short4(RValue<Int> cast)
 	{
 		Value *extend = Nucleus::createZExt(cast.value, Long::getType());
@@ -2944,6 +2960,21 @@
 		assert(false && "UNIMPLEMENTED"); return RValue<UShort4>(V(nullptr));
 	}
 
+	RValue<UShort4> operator&(RValue<UShort4> lhs, RValue<UShort4> rhs)
+	{
+		assert(false && "UNIMPLEMENTED"); return RValue<UShort4>(V(nullptr));
+	}
+
+	RValue<UShort4> operator|(RValue<UShort4> lhs, RValue<UShort4> rhs)
+	{
+		assert(false && "UNIMPLEMENTED"); return RValue<UShort4>(V(nullptr));
+	}
+
+	RValue<UShort4> operator^(RValue<UShort4> lhs, RValue<UShort4> rhs)
+	{
+		assert(false && "UNIMPLEMENTED"); return RValue<UShort4>(V(nullptr));
+	}
+
 	RValue<UShort4> operator<<(RValue<UShort4> lhs, unsigned char rhs)
 	{
 		assert(false && "UNIMPLEMENTED"); return RValue<UShort4>(V(nullptr));