Unsigned int GLSL parsing fixed

Unsigned integers in GLSL were being parsed using the regular
integer parser, so it was limited to INT_MAX. All values from
INT_MAX + 1 to UINT_MAX could not be parsed properly.

Also, added constant folding for the 4 bit conversion glsl
functions.

Fixes shader compilation issue in the Epic Zen Garden example:
https://s3.amazonaws.com/mozilla-games/ZenGarden/EpicZenGarden.html
(unfortunately, the screen is still black, so there are other
 issues left)

Fixes WebGL 2 test: conformance2/glsl3/float-parsing.html

Change-Id: Iae52b2c8e083f0e1a22599e5a583297b9850444d
Reviewed-on: https://swiftshader-review.googlesource.com/16648
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/OpenGL/compiler/Intermediate.cpp b/src/OpenGL/compiler/Intermediate.cpp
index 4293868..fbcb16b 100644
--- a/src/OpenGL/compiler/Intermediate.cpp
+++ b/src/OpenGL/compiler/Intermediate.cpp
@@ -1778,10 +1778,12 @@
 		//
 		TIntermConstantUnion *newNode = 0;
 		ConstantUnion* tempConstArray = new ConstantUnion[objectSize];
+		TType type = getType();
+		TBasicType basicType = type.getBasicType();
 		for (size_t i = 0; i < objectSize; i++) {
 			switch(op) {
 				case EOpNegative:
-					switch (getType().getBasicType()) {
+					switch (basicType) {
 						case EbtFloat: tempConstArray[i].setFConst(-unionArray[i].getFConst()); break;
 						case EbtInt:   tempConstArray[i].setIConst(-unionArray[i].getIConst()); break;
 						default:
@@ -1790,7 +1792,7 @@
 					}
 					break;
 				case EOpLogicalNot: // this code is written for possible future use, will not get executed currently
-					switch (getType().getBasicType()) {
+					switch (basicType) {
 						case EbtBool:  tempConstArray[i].setBConst(!unionArray[i].getBConst()); break;
 						default:
 							infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
@@ -1798,7 +1800,7 @@
 					}
 					break;
 				case EOpBitwiseNot:
-					switch(getType().getBasicType()) {
+					switch(basicType) {
 						case EbtInt: tempConstArray[i].setIConst(~unionArray[i].getIConst()); break;
 						case EbtUInt: tempConstArray[i].setUConst(~unionArray[i].getUConst()); break;
 						default:
@@ -1807,7 +1809,7 @@
 					}
 					break;
 				case EOpRadians:
-					switch(getType().getBasicType()) {
+					switch(basicType) {
 					case EbtFloat: tempConstArray[i].setFConst(unionArray[i].getFConst() * 1.74532925e-2f); break;
 					default:
 						infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
@@ -1815,7 +1817,7 @@
 					}
 					break;
 				case EOpDegrees:
-					switch(getType().getBasicType()) {
+					switch(basicType) {
 					case EbtFloat: tempConstArray[i].setFConst(unionArray[i].getFConst() * 5.72957795e+1f); break;
 					default:
 						infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
@@ -1823,7 +1825,7 @@
 					}
 					break;
 				case EOpSin:
-					switch(getType().getBasicType()) {
+					switch(basicType) {
 					case EbtFloat: tempConstArray[i].setFConst(sinf(unionArray[i].getFConst())); break;
 					default:
 						infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
@@ -1831,7 +1833,7 @@
 					}
 					break;
 				case EOpCos:
-					switch(getType().getBasicType()) {
+					switch(basicType) {
 					case EbtFloat: tempConstArray[i].setFConst(cosf(unionArray[i].getFConst())); break;
 					default:
 						infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
@@ -1839,7 +1841,7 @@
 					}
 					break;
 				case EOpTan:
-					switch(getType().getBasicType()) {
+					switch(basicType) {
 					case EbtFloat: tempConstArray[i].setFConst(tanf(unionArray[i].getFConst())); break;
 					default:
 						infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
@@ -1847,7 +1849,7 @@
 					}
 					break;
 				case EOpAsin:
-					switch(getType().getBasicType()) {
+					switch(basicType) {
 					case EbtFloat: tempConstArray[i].setFConst(asinf(unionArray[i].getFConst())); break;
 					default:
 						infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
@@ -1855,7 +1857,7 @@
 					}
 					break;
 				case EOpAcos:
-					switch(getType().getBasicType()) {
+					switch(basicType) {
 					case EbtFloat: tempConstArray[i].setFConst(acosf(unionArray[i].getFConst())); break;
 					default:
 						infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
@@ -1863,7 +1865,7 @@
 					}
 					break;
 				case EOpAtan:
-					switch(getType().getBasicType()) {
+					switch(basicType) {
 					case EbtFloat: tempConstArray[i].setFConst(atanf(unionArray[i].getFConst())); break;
 					default:
 						infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
@@ -1871,7 +1873,7 @@
 					}
 					break;
 				case EOpSinh:
-					switch(getType().getBasicType()) {
+					switch(basicType) {
 					case EbtFloat: tempConstArray[i].setFConst(sinhf(unionArray[i].getFConst())); break;
 					default:
 						infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
@@ -1879,7 +1881,7 @@
 					}
 					break;
 				case EOpCosh:
-					switch(getType().getBasicType()) {
+					switch(basicType) {
 					case EbtFloat: tempConstArray[i].setFConst(coshf(unionArray[i].getFConst())); break;
 					default:
 						infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
@@ -1887,7 +1889,7 @@
 					}
 					break;
 				case EOpTanh:
-					switch(getType().getBasicType()) {
+					switch(basicType) {
 					case EbtFloat: tempConstArray[i].setFConst(tanhf(unionArray[i].getFConst())); break;
 					default:
 						infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
@@ -1895,7 +1897,7 @@
 					}
 					break;
 				case EOpAsinh:
-					switch(getType().getBasicType()) {
+					switch(basicType) {
 					case EbtFloat: tempConstArray[i].setFConst(asinhf(unionArray[i].getFConst())); break;
 					default:
 						infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
@@ -1903,7 +1905,7 @@
 					}
 					break;
 				case EOpAcosh:
-					switch(getType().getBasicType()) {
+					switch(basicType) {
 					case EbtFloat: tempConstArray[i].setFConst(acoshf(unionArray[i].getFConst())); break;
 					default:
 						infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
@@ -1911,7 +1913,7 @@
 					}
 					break;
 				case EOpAtanh:
-					switch(getType().getBasicType()) {
+					switch(basicType) {
 					case EbtFloat: tempConstArray[i].setFConst(atanhf(unionArray[i].getFConst())); break;
 					default:
 						infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
@@ -1919,7 +1921,7 @@
 					}
 					break;
 				case EOpLog:
-					switch(getType().getBasicType()) {
+					switch(basicType) {
 					case EbtFloat: tempConstArray[i].setFConst(logf(unionArray[i].getFConst())); break;
 					default:
 						infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
@@ -1927,7 +1929,7 @@
 					}
 					break;
 				case EOpLog2:
-					switch(getType().getBasicType()) {
+					switch(basicType) {
 					case EbtFloat: tempConstArray[i].setFConst(sw::log2(unionArray[i].getFConst())); break;
 					default:
 						infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
@@ -1935,7 +1937,7 @@
 					}
 					break;
 				case EOpExp:
-					switch(getType().getBasicType()) {
+					switch(basicType) {
 					case EbtFloat: tempConstArray[i].setFConst(expf(unionArray[i].getFConst())); break;
 					default:
 						infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
@@ -1943,7 +1945,7 @@
 					}
 					break;
 				case EOpExp2:
-					switch(getType().getBasicType()) {
+					switch(basicType) {
 					case EbtFloat: tempConstArray[i].setFConst(exp2f(unionArray[i].getFConst())); break;
 					default:
 						infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
@@ -1951,7 +1953,7 @@
 					}
 					break;
 				case EOpSqrt:
-					switch(getType().getBasicType()) {
+					switch(basicType) {
 					case EbtFloat: tempConstArray[i].setFConst(sqrtf(unionArray[i].getFConst())); break;
 					default:
 						infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
@@ -1959,18 +1961,63 @@
 					}
 					break;
 				case EOpInverseSqrt:
-					switch(getType().getBasicType()) {
+					switch(basicType) {
 					case EbtFloat: tempConstArray[i].setFConst(1.0f / sqrtf(unionArray[i].getFConst())); break;
 					default:
 						infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
 						return 0;
 					}
 					break;
+				case EOpFloatBitsToInt:
+					switch(basicType) {
+					case EbtFloat:
+						tempConstArray[i].setIConst(sw::bitCast<int>(unionArray[i].getFConst()));
+						type.setBasicType(EbtInt);
+						break;
+					default:
+						infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
+						return 0;
+					}
+					break;
+					break;
+				case EOpFloatBitsToUint:
+					switch(basicType) {
+					case EbtFloat:
+						tempConstArray[i].setUConst(sw::bitCast<unsigned int>(unionArray[i].getFConst()));
+						type.setBasicType(EbtUInt);
+						break;
+					default:
+						infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
+						return 0;
+					}
+					break;
+				case EOpIntBitsToFloat:
+					switch(basicType) {
+					case EbtInt:
+						tempConstArray[i].setFConst(sw::bitCast<float>(unionArray[i].getIConst()));
+						type.setBasicType(EbtFloat);
+						break;
+					default:
+						infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
+						return 0;
+					}
+					break;
+				case EOpUintBitsToFloat:
+					switch(basicType) {
+					case EbtUInt:
+						tempConstArray[i].setFConst(sw::bitCast<float>(unionArray[i].getUConst()));
+						type.setBasicType(EbtFloat);
+						break;
+					default:
+						infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", getLine());
+						return 0;
+					}
+					break;
 				default:
 					return 0;
 			}
 		}
-		newNode = new TIntermConstantUnion(tempConstArray, getType());
+		newNode = new TIntermConstantUnion(tempConstArray, type);
 		newNode->setLine(getLine());
 		return newNode;
 	}