Add ESSL 3.10 integer math built-ins

This adds built-ins found in ESSL 3.10 section 8.8 Integer functions.

This includes constant folding support for functions that may be
constant folded, and support for both GLSL and HLSL output. In HLSL
several of the functions need to be emulated.

The precision qualification for the return value of some of these
functions is determined by special rules, that are now part of type
promotion for TIntermUnary nodes and determining the type of
TIntermAggregate nodes.

BUG=angleproject:1730
TEST=angle_unittests
TEST=dEQP-GLES31.functional.shaders.builtin_functions.integer.*

Change-Id: Ib0056c17671c42b6496c2f0ef059b99f8f25c122
Reviewed-on: https://chromium-review.googlesource.com/431310
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/compiler/translator/SymbolTable.cpp b/src/compiler/translator/SymbolTable.cpp
index beda47a..c9ccd2b 100644
--- a/src/compiler/translator/SymbolTable.cpp
+++ b/src/compiler/translator/SymbolTable.cpp
@@ -223,13 +223,14 @@
     switch (type->getBasicType())
     {
         case EbtGenType:
-            return TCache::getType(EbtFloat, static_cast<unsigned char>(size));
+            return TCache::getType(EbtFloat, type->getQualifier(),
+                                   static_cast<unsigned char>(size));
         case EbtGenIType:
-            return TCache::getType(EbtInt, static_cast<unsigned char>(size));
+            return TCache::getType(EbtInt, type->getQualifier(), static_cast<unsigned char>(size));
         case EbtGenUType:
-            return TCache::getType(EbtUInt, static_cast<unsigned char>(size));
+            return TCache::getType(EbtUInt, type->getQualifier(), static_cast<unsigned char>(size));
         case EbtGenBType:
-            return TCache::getType(EbtBool, static_cast<unsigned char>(size));
+            return TCache::getType(EbtBool, type->getQualifier(), static_cast<unsigned char>(size));
         default:
             return type;
     }
@@ -364,18 +365,19 @@
             insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
         }
     }
-    else if (IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3))
+    else if (IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3) ||
+             IsGenType(ptype4))
     {
-        ASSERT(!ptype4 && !ptype5);
+        ASSERT(!ptype5);
         insertUnmangledBuiltInName(name, level);
         insertBuiltIn(level, op, ext, SpecificType(rvalue, 1), name, SpecificType(ptype1, 1),
-                      SpecificType(ptype2, 1), SpecificType(ptype3, 1));
+                      SpecificType(ptype2, 1), SpecificType(ptype3, 1), SpecificType(ptype4, 1));
         insertBuiltIn(level, op, ext, SpecificType(rvalue, 2), name, SpecificType(ptype1, 2),
-                      SpecificType(ptype2, 2), SpecificType(ptype3, 2));
+                      SpecificType(ptype2, 2), SpecificType(ptype3, 2), SpecificType(ptype4, 2));
         insertBuiltIn(level, op, ext, SpecificType(rvalue, 3), name, SpecificType(ptype1, 3),
-                      SpecificType(ptype2, 3), SpecificType(ptype3, 3));
+                      SpecificType(ptype2, 3), SpecificType(ptype3, 3), SpecificType(ptype4, 3));
         insertBuiltIn(level, op, ext, SpecificType(rvalue, 4), name, SpecificType(ptype1, 4),
-                      SpecificType(ptype2, 4), SpecificType(ptype3, 4));
+                      SpecificType(ptype2, 4), SpecificType(ptype3, 4), SpecificType(ptype4, 4));
     }
     else if (IsVecType(rvalue) || IsVecType(ptype1) || IsVecType(ptype2) || IsVecType(ptype3))
     {