Fixed the compound-assignment-type-combination.html test

The fix is in 2 parts:
1) Multiplying a matrix by a float was failing due to attempting
to use the matrix's index on the float, thus going out of bounds.
2) Multiplying a vector or matrix by vectors or matrices of a
different size was not causing a failure, but now it does.

BUG=18450319

Change-Id: Ie01a77eb32d7d52fcd0a803f3e5efc24c625dbfd
Reviewed-on: https://swiftshader-review.googlesource.com/1450
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/OpenGL/compiler/OutputASM.cpp b/src/OpenGL/compiler/OutputASM.cpp
index e8aa3f3..ff73893 100644
--- a/src/OpenGL/compiler/OutputASM.cpp
+++ b/src/OpenGL/compiler/OutputASM.cpp
@@ -1432,7 +1432,7 @@
 			TIntermTyped *arg = argument->getAsTyped();

 			const TType &type = arg->getType();

 			const TTypeList *structure = type.getStruct();

-			ASSERT(index < arg->totalRegisterCount());

+			index = (index >= arg->totalRegisterCount()) ? arg->totalRegisterCount() - 1 : index;

 

 			int size = registerSize(type, index);

 

@@ -1522,8 +1522,15 @@
 		       (swizzleElement(leftSwizzle, swizzleElement(rightSwizzle, 3)) << 6);

 	}

 

-	void OutputASM::assignLvalue(TIntermTyped *dst, TIntermNode *src)

+	void OutputASM::assignLvalue(TIntermTyped *dst, TIntermTyped *src)

 	{

+		if(src &&

+			((src->isVector() && (!dst->isVector() || (dst->getNominalSize() != dst->getNominalSize()))) ||

+			 (src->isMatrix() && (!dst->isMatrix() || (src->getNominalSize() != dst->getNominalSize())))))

+		{

+			return mContext.error(src->getLine(), "Result type should match the l-value type in compound assignment", src->isVector() ? "vector" : "matrix");

+		}

+

 		TIntermBinary *binary = dst->getAsBinaryNode();

 

 		if(binary && binary->getOp() == EOpIndexIndirect && dst->isScalar())

diff --git a/src/OpenGL/compiler/OutputASM.h b/src/OpenGL/compiler/OutputASM.h
index ae6cfa7..4f0ae3d 100644
--- a/src/OpenGL/compiler/OutputASM.h
+++ b/src/OpenGL/compiler/OutputASM.h
@@ -113,7 +113,7 @@
 		void emitCmp(sw::Shader::Control cmpOp, TIntermTyped *dst, TIntermNode *left, TIntermNode *right, int index = 0);

 		void argument(sw::Shader::SourceParameter &parameter, TIntermNode *argument, int index = 0);

 		void copy(TIntermTyped *dst, TIntermNode *src, int offset = 0);

-		void assignLvalue(TIntermTyped *dst, TIntermNode *src);

+		void assignLvalue(TIntermTyped *dst, TIntermTyped *src);

 		int lvalue(sw::Shader::DestinationParameter &dst, Temporary &address, TIntermTyped *node);

 		sw::Shader::ParameterType registerType(TIntermTyped *operand);

 		int registerIndex(TIntermTyped *operand);

diff --git a/src/Radiance/compiler/OutputASM.cpp b/src/Radiance/compiler/OutputASM.cpp
index b85edf6..07b4bf0 100644
--- a/src/Radiance/compiler/OutputASM.cpp
+++ b/src/Radiance/compiler/OutputASM.cpp
@@ -1432,7 +1432,7 @@
 			TIntermTyped *arg = argument->getAsTyped();

 			const TType &type = arg->getType();

 			const TTypeList *structure = type.getStruct();

-			ASSERT(index < arg->totalRegisterCount());

+			index = (index >= arg->totalRegisterCount()) ? arg->totalRegisterCount() - 1 : index;

 

 			int size = registerSize(type, index);

 

@@ -1522,8 +1522,15 @@
 		       (swizzleElement(leftSwizzle, swizzleElement(rightSwizzle, 3)) << 6);

 	}

 

-	void OutputASM::assignLvalue(TIntermTyped *dst, TIntermNode *src)

+	void OutputASM::assignLvalue(TIntermTyped *dst, TIntermTyped *src)

 	{

+		if(src &&

+			((src->isVector() && (!dst->isVector() || (dst->getNominalSize() != dst->getNominalSize()))) ||

+			 (src->isMatrix() && (!dst->isMatrix() || (src->getNominalSize() != dst->getNominalSize())))))

+		{

+			return mContext.error(src->getLine(), "Result type should match the l-value type in compound assignment", src->isVector() ? "vector" : "matrix");

+		}

+

 		TIntermBinary *binary = dst->getAsBinaryNode();

 

 		if(binary && binary->getOp() == EOpIndexIndirect && dst->isScalar())

diff --git a/src/Radiance/compiler/OutputASM.h b/src/Radiance/compiler/OutputASM.h
index a40fc36..fb58700 100644
--- a/src/Radiance/compiler/OutputASM.h
+++ b/src/Radiance/compiler/OutputASM.h
@@ -113,7 +113,7 @@
 		void emitCmp(sw::Shader::Control cmpOp, TIntermTyped *dst, TIntermNode *left, TIntermNode *right, int index = 0);

 		void argument(sw::Shader::SourceParameter &parameter, TIntermNode *argument, int index = 0);

 		void copy(TIntermTyped *dst, TIntermNode *src, int offset = 0);

-		void assignLvalue(TIntermTyped *dst, TIntermNode *src);

+		void assignLvalue(TIntermTyped *dst, TIntermTyped *src);

 		int lvalue(sw::Shader::DestinationParameter &dst, Temporary &address, TIntermTyped *node);

 		sw::Shader::ParameterType registerType(TIntermTyped *operand);

 		int registerIndex(TIntermTyped *operand);