AST: dump attributes along with control flow.
[platform/upstream/glslang.git] / glslang / MachineIndependent / intermOut.cpp
index a5a6f2c..4c01284 100644 (file)
@@ -1,12 +1,12 @@
 //
-//Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
-//Copyright (C) 2012-2016 LunarG, Inc.
+// Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
+// Copyright (C) 2012-2016 LunarG, Inc.
 //
-//All rights reserved.
+// All rights reserved.
 //
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
 //
 //    Redistributions of source code must retain the above copyright
 //    notice, this list of conditions and the following disclaimer.
 //    contributors may be used to endorse or promote products derived
 //    from this software without specific prior written permission.
 //
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
 //
 
 #include "localintermediate.h"
 #include "../Include/InfoSink.h"
 
 #ifdef _MSC_VER
-#include <float.h>
-#elif defined __ANDROID__ || defined __linux__ || __MINGW32__ || __MINGW64__
-#include <cmath>
+#include <cfloat>
 #else
-#include <math.h>
+#include <cmath>
 #endif
 
 namespace {
 
-bool is_positive_infinity(double x) {
+bool IsInfinity(double x) {
 #ifdef _MSC_VER
-  return _fpclass(x) == _FPCLASS_PINF;
-#elif defined __ANDROID__ || defined __linux__ || __MINGW32__ || __MINGW64__
-  return std::isinf(x) && (x >= 0);
+    switch (_fpclass(x)) {
+    case _FPCLASS_NINF:
+    case _FPCLASS_PINF:
+        return true;
+    default:
+        return false;
+    }
 #else
-  return isinf(x) && (x >= 0);
+    return std::isinf(x);
+#endif
+}
+
+bool IsNan(double x) {
+#ifdef _MSC_VER
+    switch (_fpclass(x)) {
+    case _FPCLASS_SNAN:
+    case _FPCLASS_QNAN:
+        return true;
+    default:
+        return false;
+    }
+#else
+  return std::isnan(x);
 #endif
 }
 
@@ -150,6 +166,7 @@ bool TOutputTraverser::visitBinary(TVisit /* visit */, TIntermBinary* node)
         out.debug << (*node->getLeft()->getType().getStruct())[node->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst()].type->getFieldName();
         out.debug << ": direct index for structure";      break;
     case EOpVectorSwizzle: out.debug << "vector swizzle"; break;
+    case EOpMatrixSwizzle: out.debug << "matrix swizzle"; break;
 
     case EOpAdd:    out.debug << "add";                     break;
     case EOpSub:    out.debug << "subtract";                break;
@@ -167,6 +184,8 @@ bool TOutputTraverser::visitBinary(TVisit /* visit */, TIntermBinary* node)
     case EOpGreaterThan:      out.debug << "Compare Greater Than";          break;
     case EOpLessThanEqual:    out.debug << "Compare Less Than or Equal";    break;
     case EOpGreaterThanEqual: out.debug << "Compare Greater Than or Equal"; break;
+    case EOpVectorEqual:      out.debug << "Equal";                         break;
+    case EOpVectorNotEqual:   out.debug << "NotEqual";                      break;
 
     case EOpVectorTimesScalar: out.debug << "vector-scale";          break;
     case EOpVectorTimesMatrix: out.debug << "vector-times-matrix";   break;
@@ -177,6 +196,7 @@ bool TOutputTraverser::visitBinary(TVisit /* visit */, TIntermBinary* node)
     case EOpLogicalOr:  out.debug << "logical-or";   break;
     case EOpLogicalXor: out.debug << "logical-xor"; break;
     case EOpLogicalAnd: out.debug << "logical-and"; break;
+
     default: out.debug << "<unknown op>";
     }
 
@@ -289,6 +309,13 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
     case EOpDoubleBitsToUint64: out.debug << "doubleBitsToUint64"; break;
     case EOpInt64BitsToDouble:  out.debug << "int64BitsToDouble";  break;
     case EOpUint64BitsToDouble: out.debug << "uint64BitsToDouble"; break;
+#ifdef AMD_EXTENSIONS
+    case EOpFloat16BitsToInt16:  out.debug << "float16BitsToInt16";  break;
+    case EOpFloat16BitsToUint16: out.debug << "float16BitsToUint16"; break;
+    case EOpInt16BitsToFloat16:  out.debug << "int16BitsToFloat16";  break;
+    case EOpUint16BitsToFloat16: out.debug << "uint16BitsToFloat16"; break;
+#endif
+
     case EOpPackSnorm2x16:  out.debug << "packSnorm2x16";        break;
     case EOpUnpackSnorm2x16:out.debug << "unpackSnorm2x16";      break;
     case EOpPackUnorm2x16:  out.debug << "packUnorm2x16";        break;
@@ -308,6 +335,21 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
     case EOpPackUint2x32:     out.debug << "packUint2x32";       break;
     case EOpUnpackUint2x32:   out.debug << "unpackUint2x32";     break;
 
+#ifdef AMD_EXTENSIONS
+    case EOpPackInt2x16:      out.debug << "packInt2x16";        break;
+    case EOpUnpackInt2x16:    out.debug << "unpackInt2x16";      break;
+    case EOpPackUint2x16:     out.debug << "packUint2x16";       break;
+    case EOpUnpackUint2x16:   out.debug << "unpackUint2x16";     break;
+
+    case EOpPackInt4x16:      out.debug << "packInt4x16";        break;
+    case EOpUnpackInt4x16:    out.debug << "unpackInt4x16";      break;
+    case EOpPackUint4x16:     out.debug << "packUint4x16";       break;
+    case EOpUnpackUint4x16:   out.debug << "unpackUint4x16";     break;
+
+    case EOpPackFloat2x16:    out.debug << "packFloat2x16";      break;
+    case EOpUnpackFloat2x16:  out.debug << "unpackFloat2x16";    break;
+#endif
+
     case EOpLength:         out.debug << "length";               break;
     case EOpNormalize:      out.debug << "normalize";            break;
     case EOpDPdx:           out.debug << "dPdx";                 break;
@@ -355,6 +397,7 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
 
     case EOpBallot:                 out.debug << "ballot";                break;
     case EOpReadFirstInvocation:    out.debug << "readFirstInvocation";   break;
+
     case EOpAnyInvocation:          out.debug << "anyInvocation";         break;
     case EOpAllInvocations:         out.debug << "allInvocations";        break;
     case EOpAllInvocationsEqual:    out.debug << "allInvocationsEqual";   break;
@@ -365,6 +408,93 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
     case EOpRcp:                    out.debug << "rcp";                   break;
     case EOpSaturate:               out.debug << "saturate";              break;
 
+    case EOpSparseTexelsResident:   out.debug << "sparseTexelsResident";  break;
+
+#ifdef AMD_EXTENSIONS
+    case EOpMinInvocations:             out.debug << "minInvocations";              break;
+    case EOpMaxInvocations:             out.debug << "maxInvocations";              break;
+    case EOpAddInvocations:             out.debug << "addInvocations";              break;
+    case EOpMinInvocationsNonUniform:   out.debug << "minInvocationsNonUniform";    break;
+    case EOpMaxInvocationsNonUniform:   out.debug << "maxInvocationsNonUniform";    break;
+    case EOpAddInvocationsNonUniform:   out.debug << "addInvocationsNonUniform";    break;
+
+    case EOpMinInvocationsInclusiveScan:            out.debug << "minInvocationsInclusiveScan";             break;
+    case EOpMaxInvocationsInclusiveScan:            out.debug << "maxInvocationsInclusiveScan";             break;
+    case EOpAddInvocationsInclusiveScan:            out.debug << "addInvocationsInclusiveScan";             break;
+    case EOpMinInvocationsInclusiveScanNonUniform:  out.debug << "minInvocationsInclusiveScanNonUniform";   break;
+    case EOpMaxInvocationsInclusiveScanNonUniform:  out.debug << "maxInvocationsInclusiveScanNonUniform";   break;
+    case EOpAddInvocationsInclusiveScanNonUniform:  out.debug << "addInvocationsInclusiveScanNonUniform";   break;
+
+    case EOpMinInvocationsExclusiveScan:            out.debug << "minInvocationsExclusiveScan";             break;
+    case EOpMaxInvocationsExclusiveScan:            out.debug << "maxInvocationsExclusiveScan";             break;
+    case EOpAddInvocationsExclusiveScan:            out.debug << "addInvocationsExclusiveScan";             break;
+    case EOpMinInvocationsExclusiveScanNonUniform:  out.debug << "minInvocationsExclusiveScanNonUniform";   break;
+    case EOpMaxInvocationsExclusiveScanNonUniform:  out.debug << "maxInvocationsExclusiveScanNonUniform";   break;
+    case EOpAddInvocationsExclusiveScanNonUniform:  out.debug << "addInvocationsExclusiveScanNonUniform";   break;
+
+    case EOpMbcnt:                  out.debug << "mbcnt";                       break;
+
+    case EOpCubeFaceIndex:          out.debug << "cubeFaceIndex";               break;
+    case EOpCubeFaceCoord:          out.debug << "cubeFaceCoord";               break;
+
+    case EOpFragmentMaskFetch:      out.debug << "fragmentMaskFetchAMD";        break;
+    case EOpFragmentFetch:          out.debug << "fragmentFetchAMD";            break;
+
+    case EOpConvBoolToFloat16:      out.debug << "Convert bool to float16";     break;
+    case EOpConvIntToFloat16:       out.debug << "Convert int to float16";      break;
+    case EOpConvUintToFloat16:      out.debug << "Convert uint to float16";     break;
+    case EOpConvFloatToFloat16:     out.debug << "Convert float to float16";    break;
+    case EOpConvDoubleToFloat16:    out.debug << "Convert double to float16";   break;
+    case EOpConvInt64ToFloat16:     out.debug << "Convert int64 to float16";    break;
+    case EOpConvUint64ToFloat16:    out.debug << "Convert uint64 to float16";   break;
+    case EOpConvFloat16ToBool:      out.debug << "Convert float16 to bool";     break;
+    case EOpConvFloat16ToInt:       out.debug << "Convert float16 to int";      break;
+    case EOpConvFloat16ToUint:      out.debug << "Convert float16 to uint";     break;
+    case EOpConvFloat16ToFloat:     out.debug << "Convert float16 to float";    break;
+    case EOpConvFloat16ToDouble:    out.debug << "Convert float16 to double";   break;
+    case EOpConvFloat16ToInt64:     out.debug << "Convert float16 to int64";    break;
+    case EOpConvFloat16ToUint64:    out.debug << "Convert float16 to uint64";   break;
+
+    case EOpConvBoolToInt16:        out.debug << "Convert bool to int16";       break;
+    case EOpConvIntToInt16:         out.debug << "Convert int to int16";        break;
+    case EOpConvUintToInt16:        out.debug << "Convert uint to int16";       break;
+    case EOpConvFloatToInt16:       out.debug << "Convert float to int16";      break;
+    case EOpConvDoubleToInt16:      out.debug << "Convert double to int16";     break;
+    case EOpConvFloat16ToInt16:     out.debug << "Convert float16 to int16";    break;
+    case EOpConvInt64ToInt16:       out.debug << "Convert int64 to int16";      break;
+    case EOpConvUint64ToInt16:      out.debug << "Convert uint64 to int16";     break;
+    case EOpConvUint16ToInt16:      out.debug << "Convert uint16 to int16";     break;
+    case EOpConvInt16ToBool:        out.debug << "Convert int16 to bool";       break;
+    case EOpConvInt16ToInt:         out.debug << "Convert int16 to int";        break;
+    case EOpConvInt16ToUint:        out.debug << "Convert int16 to uint";       break;
+    case EOpConvInt16ToFloat:       out.debug << "Convert int16 to float";      break;
+    case EOpConvInt16ToDouble:      out.debug << "Convert int16 to double";     break;
+    case EOpConvInt16ToFloat16:     out.debug << "Convert int16 to float16";    break;
+    case EOpConvInt16ToInt64:       out.debug << "Convert int16 to int64";      break;
+    case EOpConvInt16ToUint64:      out.debug << "Convert int16 to uint64";     break;
+
+    case EOpConvBoolToUint16:       out.debug << "Convert bool to uint16";      break;
+    case EOpConvIntToUint16:        out.debug << "Convert int to uint16";       break;
+    case EOpConvUintToUint16:       out.debug << "Convert uint to uint16";      break;
+    case EOpConvFloatToUint16:      out.debug << "Convert float to uint16";     break;
+    case EOpConvDoubleToUint16:     out.debug << "Convert double to uint16";    break;
+    case EOpConvFloat16ToUint16:    out.debug << "Convert float16 to uint16";   break;
+    case EOpConvInt64ToUint16:      out.debug << "Convert int64 to uint16";     break;
+    case EOpConvUint64ToUint16:     out.debug << "Convert uint64 to uint16";    break;
+    case EOpConvInt16ToUint16:      out.debug << "Convert int16 to uint16";     break;
+    case EOpConvUint16ToBool:       out.debug << "Convert uint16 to bool";      break;
+    case EOpConvUint16ToInt:        out.debug << "Convert uint16 to int";       break;
+    case EOpConvUint16ToUint:       out.debug << "Convert uint16 to uint";      break;
+    case EOpConvUint16ToFloat:      out.debug << "Convert uint16 to float";     break;
+    case EOpConvUint16ToDouble:     out.debug << "Convert uint16 to double";    break;
+    case EOpConvUint16ToFloat16:    out.debug << "Convert uint16 to float16";   break;
+    case EOpConvUint16ToInt64:      out.debug << "Convert uint16 to int64";     break;
+    case EOpConvUint16ToUint64:     out.debug << "Convert uint16 to uint64";    break;
+#endif
+
+    case EOpSubpassLoad:   out.debug << "subpassLoad";   break;
+    case EOpSubpassLoadMS: out.debug << "subpassLoadMS"; break;
+
     default: out.debug.message(EPrefixError, "Bad unary op");
     }
 
@@ -396,9 +526,13 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
 
     case EOpConstructFloat: out.debug << "Construct float"; break;
     case EOpConstructDouble:out.debug << "Construct double"; break;
+
     case EOpConstructVec2:  out.debug << "Construct vec2";  break;
     case EOpConstructVec3:  out.debug << "Construct vec3";  break;
     case EOpConstructVec4:  out.debug << "Construct vec4";  break;
+    case EOpConstructDVec2: out.debug << "Construct dvec2";  break;
+    case EOpConstructDVec3: out.debug << "Construct dvec3";  break;
+    case EOpConstructDVec4: out.debug << "Construct dvec4";  break;
     case EOpConstructBool:  out.debug << "Construct bool";  break;
     case EOpConstructBVec2: out.debug << "Construct bvec2"; break;
     case EOpConstructBVec3: out.debug << "Construct bvec3"; break;
@@ -419,6 +553,16 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
     case EOpConstructU64Vec2: out.debug << "Construct u64vec2"; break;
     case EOpConstructU64Vec3: out.debug << "Construct u64vec3"; break;
     case EOpConstructU64Vec4: out.debug << "Construct u64vec4"; break;
+#ifdef AMD_EXTENSIONS
+    case EOpConstructInt16:   out.debug << "Construct int16_t"; break;
+    case EOpConstructI16Vec2: out.debug << "Construct i16vec2"; break;
+    case EOpConstructI16Vec3: out.debug << "Construct i16vec3"; break;
+    case EOpConstructI16Vec4: out.debug << "Construct i16vec4"; break;
+    case EOpConstructUint16:  out.debug << "Construct uint16_t"; break;
+    case EOpConstructU16Vec2: out.debug << "Construct u16vec2"; break;
+    case EOpConstructU16Vec3: out.debug << "Construct u16vec3"; break;
+    case EOpConstructU16Vec4: out.debug << "Construct u16vec4"; break;
+#endif
     case EOpConstructMat2x2:  out.debug << "Construct mat2";    break;
     case EOpConstructMat2x3:  out.debug << "Construct mat2x3";  break;
     case EOpConstructMat2x4:  out.debug << "Construct mat2x4";  break;
@@ -437,6 +581,48 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
     case EOpConstructDMat4x2: out.debug << "Construct dmat4x2"; break;
     case EOpConstructDMat4x3: out.debug << "Construct dmat4x3"; break;
     case EOpConstructDMat4x4: out.debug << "Construct dmat4";   break;
+    case EOpConstructIMat2x2: out.debug << "Construct imat2";   break;
+    case EOpConstructIMat2x3: out.debug << "Construct imat2x3"; break;
+    case EOpConstructIMat2x4: out.debug << "Construct imat2x4"; break;
+    case EOpConstructIMat3x2: out.debug << "Construct imat3x2"; break;
+    case EOpConstructIMat3x3: out.debug << "Construct imat3";   break;
+    case EOpConstructIMat3x4: out.debug << "Construct imat3x4"; break;
+    case EOpConstructIMat4x2: out.debug << "Construct imat4x2"; break;
+    case EOpConstructIMat4x3: out.debug << "Construct imat4x3"; break;
+    case EOpConstructIMat4x4: out.debug << "Construct imat4";   break;
+    case EOpConstructUMat2x2: out.debug << "Construct umat2";   break;
+    case EOpConstructUMat2x3: out.debug << "Construct umat2x3"; break;
+    case EOpConstructUMat2x4: out.debug << "Construct umat2x4"; break;
+    case EOpConstructUMat3x2: out.debug << "Construct umat3x2"; break;
+    case EOpConstructUMat3x3: out.debug << "Construct umat3";   break;
+    case EOpConstructUMat3x4: out.debug << "Construct umat3x4"; break;
+    case EOpConstructUMat4x2: out.debug << "Construct umat4x2"; break;
+    case EOpConstructUMat4x3: out.debug << "Construct umat4x3"; break;
+    case EOpConstructUMat4x4: out.debug << "Construct umat4";   break;
+    case EOpConstructBMat2x2: out.debug << "Construct bmat2";   break;
+    case EOpConstructBMat2x3: out.debug << "Construct bmat2x3"; break;
+    case EOpConstructBMat2x4: out.debug << "Construct bmat2x4"; break;
+    case EOpConstructBMat3x2: out.debug << "Construct bmat3x2"; break;
+    case EOpConstructBMat3x3: out.debug << "Construct bmat3";   break;
+    case EOpConstructBMat3x4: out.debug << "Construct bmat3x4"; break;
+    case EOpConstructBMat4x2: out.debug << "Construct bmat4x2"; break;
+    case EOpConstructBMat4x3: out.debug << "Construct bmat4x3"; break;
+    case EOpConstructBMat4x4: out.debug << "Construct bmat4";   break;
+#ifdef AMD_EXTENSIONS
+    case EOpConstructFloat16:   out.debug << "Construct float16_t"; break;
+    case EOpConstructF16Vec2:   out.debug << "Construct f16vec2";   break;
+    case EOpConstructF16Vec3:   out.debug << "Construct f16vec3";   break;
+    case EOpConstructF16Vec4:   out.debug << "Construct f16vec4";   break;
+    case EOpConstructF16Mat2x2: out.debug << "Construct f16mat2";   break;
+    case EOpConstructF16Mat2x3: out.debug << "Construct f16mat2x3"; break;
+    case EOpConstructF16Mat2x4: out.debug << "Construct f16mat2x4"; break;
+    case EOpConstructF16Mat3x2: out.debug << "Construct f16mat3x2"; break;
+    case EOpConstructF16Mat3x3: out.debug << "Construct f16mat3";   break;
+    case EOpConstructF16Mat3x4: out.debug << "Construct f16mat3x4"; break;
+    case EOpConstructF16Mat4x2: out.debug << "Construct f16mat4x2"; break;
+    case EOpConstructF16Mat4x3: out.debug << "Construct f16mat4x3"; break;
+    case EOpConstructF16Mat4x4: out.debug << "Construct f16mat4";   break;
+#endif
     case EOpConstructStruct:  out.debug << "Construct structure";  break;
     case EOpConstructTextureSampler: out.debug << "Construct combined texture-sampler"; break;
 
@@ -482,6 +668,18 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
 
     case EOpReadInvocation:             out.debug << "readInvocation";        break;
 
+#ifdef AMD_EXTENSIONS
+    case EOpSwizzleInvocations:         out.debug << "swizzleInvocations";       break;
+    case EOpSwizzleInvocationsMasked:   out.debug << "swizzleInvocationsMasked"; break;
+    case EOpWriteInvocation:            out.debug << "writeInvocation";          break;
+
+    case EOpMin3:                       out.debug << "min3";                  break;
+    case EOpMax3:                       out.debug << "max3";                  break;
+    case EOpMid3:                       out.debug << "mid3";                  break;
+
+    case EOpTime:                       out.debug << "time";                  break;
+#endif
+
     case EOpAtomicAdd:                  out.debug << "AtomicAdd";             break;
     case EOpAtomicMin:                  out.debug << "AtomicMin";             break;
     case EOpAtomicMax:                  out.debug << "AtomicMax";             break;
@@ -491,6 +689,16 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
     case EOpAtomicExchange:             out.debug << "AtomicExchange";        break;
     case EOpAtomicCompSwap:             out.debug << "AtomicCompSwap";        break;
 
+    case EOpAtomicCounterAdd:           out.debug << "AtomicCounterAdd";      break;
+    case EOpAtomicCounterSubtract:      out.debug << "AtomicCounterSubtract"; break;
+    case EOpAtomicCounterMin:           out.debug << "AtomicCounterMin";      break;
+    case EOpAtomicCounterMax:           out.debug << "AtomicCounterMax";      break;
+    case EOpAtomicCounterAnd:           out.debug << "AtomicCounterAnd";      break;
+    case EOpAtomicCounterOr:            out.debug << "AtomicCounterOr";       break;
+    case EOpAtomicCounterXor:           out.debug << "AtomicCounterXor";      break;
+    case EOpAtomicCounterExchange:      out.debug << "AtomicCounterExchange"; break;
+    case EOpAtomicCounterCompSwap:      out.debug << "AtomicCounterCompSwap"; break;
+
     case EOpImageQuerySize:             out.debug << "imageQuerySize";        break;
     case EOpImageQuerySamples:          out.debug << "imageQuerySamples";     break;
     case EOpImageLoad:                  out.debug << "imageLoad";             break;
@@ -503,6 +711,10 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
     case EOpImageAtomicXor:             out.debug << "imageAtomicXor";        break;
     case EOpImageAtomicExchange:        out.debug << "imageAtomicExchange";   break;
     case EOpImageAtomicCompSwap:        out.debug << "imageAtomicCompSwap";   break;
+#ifdef AMD_EXTENSIONS
+    case EOpImageLoadLod:               out.debug << "imageLoadLod";          break;
+    case EOpImageStoreLod:              out.debug << "imageStoreLod";         break;
+#endif
 
     case EOpTextureQuerySize:           out.debug << "textureSize";           break;
     case EOpTextureQueryLod:            out.debug << "textureQueryLod";       break;
@@ -525,6 +737,38 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
     case EOpTextureGather:              out.debug << "textureGather";         break;
     case EOpTextureGatherOffset:        out.debug << "textureGatherOffset";   break;
     case EOpTextureGatherOffsets:       out.debug << "textureGatherOffsets";  break;
+    case EOpTextureClamp:               out.debug << "textureClamp";          break;
+    case EOpTextureOffsetClamp:         out.debug << "textureOffsetClamp";    break;
+    case EOpTextureGradClamp:           out.debug << "textureGradClamp";      break;
+    case EOpTextureGradOffsetClamp:     out.debug << "textureGradOffsetClamp";  break;
+#ifdef AMD_EXTENSIONS
+    case EOpTextureGatherLod:           out.debug << "textureGatherLod";        break;
+    case EOpTextureGatherLodOffset:     out.debug << "textureGatherLodOffset";  break;
+    case EOpTextureGatherLodOffsets:    out.debug << "textureGatherLodOffsets"; break;
+#endif
+
+    case EOpSparseTexture:                  out.debug << "sparseTexture";                   break;
+    case EOpSparseTextureOffset:            out.debug << "sparseTextureOffset";             break;
+    case EOpSparseTextureLod:               out.debug << "sparseTextureLod";                break;
+    case EOpSparseTextureLodOffset:         out.debug << "sparseTextureLodOffset";          break;
+    case EOpSparseTextureFetch:             out.debug << "sparseTexelFetch";                break;
+    case EOpSparseTextureFetchOffset:       out.debug << "sparseTexelFetchOffset";          break;
+    case EOpSparseTextureGrad:              out.debug << "sparseTextureGrad";               break;
+    case EOpSparseTextureGradOffset:        out.debug << "sparseTextureGradOffset";         break;
+    case EOpSparseTextureGather:            out.debug << "sparseTextureGather";             break;
+    case EOpSparseTextureGatherOffset:      out.debug << "sparseTextureGatherOffset";       break;
+    case EOpSparseTextureGatherOffsets:     out.debug << "sparseTextureGatherOffsets";      break;
+    case EOpSparseImageLoad:                out.debug << "sparseImageLoad";                 break;
+    case EOpSparseTextureClamp:             out.debug << "sparseTextureClamp";              break;
+    case EOpSparseTextureOffsetClamp:       out.debug << "sparseTextureOffsetClamp";        break;
+    case EOpSparseTextureGradClamp:         out.debug << "sparseTextureGradClamp";          break;
+    case EOpSparseTextureGradOffsetClamp:   out.debug << "sparseTextureGradOffsetClam";     break;
+#ifdef AMD_EXTENSIONS
+    case EOpSparseTextureGatherLod:         out.debug << "sparseTextureGatherLod";          break;
+    case EOpSparseTextureGatherLodOffset:   out.debug << "sparseTextureGatherLodOffset";    break;
+    case EOpSparseTextureGatherLodOffsets:  out.debug << "sparseTextureGatherLodOffsets";   break;
+    case EOpSparseImageLoadLod:             out.debug << "sparseImageLoadLod";              break;
+#endif
 
     case EOpAddCarry:                   out.debug << "addCarry";              break;
     case EOpSubBorrow:                  out.debug << "subBorrow";             break;
@@ -539,10 +783,22 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
 
     case EOpInterpolateAtSample:   out.debug << "interpolateAtSample";    break;
     case EOpInterpolateAtOffset:   out.debug << "interpolateAtOffset";    break;
+#ifdef AMD_EXTENSIONS
+    case EOpInterpolateAtVertex:   out.debug << "interpolateAtVertex";    break;
+#endif
 
     case EOpSinCos:                     out.debug << "sincos";                break;
     case EOpGenMul:                     out.debug << "mul";                   break;
 
+    case EOpAllMemoryBarrierWithGroupSync:    out.debug << "AllMemoryBarrierWithGroupSync";    break;
+    case EOpDeviceMemoryBarrier:              out.debug << "DeviceMemoryBarrier";              break;
+    case EOpDeviceMemoryBarrierWithGroupSync: out.debug << "DeviceMemoryBarrierWithGroupSync"; break;
+    case EOpWorkgroupMemoryBarrier:           out.debug << "WorkgroupMemoryBarrier";           break;
+    case EOpWorkgroupMemoryBarrierWithGroupSync: out.debug << "WorkgroupMemoryBarrierWithGroupSync"; break;
+
+    case EOpSubpassLoad:   out.debug << "subpassLoad";   break;
+    case EOpSubpassLoadMS: out.debug << "subpassLoadMS"; break;
+
     default: out.debug.message(EPrefixError, "Bad aggregation op");
     }
 
@@ -561,7 +817,13 @@ bool TOutputTraverser::visitSelection(TVisit /* visit */, TIntermSelection* node
     OutputTreeText(out, node, depth);
 
     out.debug << "Test condition and select";
-    out.debug << " (" << node->getCompleteString() << ")\n";
+    out.debug << " (" << node->getCompleteString() << ")";
+
+    if (node->getFlatten())
+        out.debug << ": Flatten";
+    if (node->getDontFlatten())
+        out.debug << ": DontFlatten";
+    out.debug << "\n";
 
     ++depth;
 
@@ -606,13 +868,19 @@ static void OutputConstantUnion(TInfoSink& out, const TIntermTyped* node, const
             break;
         case EbtFloat:
         case EbtDouble:
+#ifdef AMD_EXTENSIONS
+        case EbtFloat16:
+#endif
             {
                 const double value = constUnion[i].getDConst();
-                // Print infinity in a portable way, for test stability.
-                // Other cases may be needed in the future: negative infinity,
-                // and NaNs.
-                if (is_positive_infinity(value))
-                    out.debug << "inf\n";
+                // Print infinities and NaNs in a portable way.
+                if (IsInfinity(value)) {
+                    if (value < 0)
+                        out.debug << "-1.#INF\n";
+                    else
+                        out.debug << "+1.#INF\n";
+                } else if (IsNan(value))
+                    out.debug << "1.#IND\n";
                 else {
                     const int maxSize = 300;
                     char buf[maxSize];
@@ -658,6 +926,26 @@ static void OutputConstantUnion(TInfoSink& out, const TIntermTyped* node, const
                 out.debug << buf << "\n";
             }
             break;
+#ifdef AMD_EXTENSIONS
+        case EbtInt16:
+            {
+                const int maxSize = 300;
+                char buf[maxSize];
+                snprintf(buf, maxSize, "%d (%s)", constUnion[i].getIConst(), "const int16_t");
+
+                out.debug << buf << "\n";
+            }
+            break;
+        case EbtUint16:
+            {
+                const int maxSize = 300;
+                char buf[maxSize];
+                snprintf(buf, maxSize, "%u (%s)", constUnion[i].getUConst(), "const uint16_t");
+
+                out.debug << buf << "\n";
+            }
+            break;
+#endif
         default:
             out.info.message(EPrefixInternalError, "Unknown constant", node->getLoc());
             break;
@@ -697,7 +985,17 @@ bool TOutputTraverser::visitLoop(TVisit /* visit */, TIntermLoop* node)
     out.debug << "Loop with condition ";
     if (! node->testFirst())
         out.debug << "not ";
-    out.debug << "tested first\n";
+    out.debug << "tested first";
+
+    if (node->getUnroll())
+        out.debug << ": Unroll";
+    if (node->getDontUnroll())
+        out.debug << ": DontUnroll";
+    if (node->getLoopDependency()) {
+        out.debug << ": Dependency ";
+        out.debug << node->getLoopDependency();
+    }
+    out.debug << "\n";
 
     ++depth;
 
@@ -758,7 +1056,13 @@ bool TOutputTraverser::visitSwitch(TVisit /* visit */, TIntermSwitch* node)
     TInfoSink& out = infoSink;
 
     OutputTreeText(out, node, depth);
-    out.debug << "switch\n";
+    out.debug << "switch";
+
+    if (node->getFlatten())
+        out.debug << ": Flatten";
+    if (node->getDontFlatten())
+        out.debug << ": DontFlatten";
+    out.debug << "\n";
 
     OutputTreeText(out, node, depth);
     out.debug << "condition\n";
@@ -798,6 +1102,13 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree)
 
     case EShLangTessControl:
         infoSink.debug << "vertices = " << vertices << "\n";
+
+        if (inputPrimitive != ElgNone)
+            infoSink.debug << "input primitive = " << TQualifier::getGeometryString(inputPrimitive) << "\n";
+        if (vertexSpacing != EvsNone)
+            infoSink.debug << "vertex spacing = " << TQualifier::getVertexSpacingString(vertexSpacing) << "\n";
+        if (vertexOrder != EvoNone)
+            infoSink.debug << "triangle order = " << TQualifier::getVertexOrderString(vertexOrder) << "\n";
         break;
 
     case EShLangTessEvaluation:
@@ -822,6 +1133,8 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree)
             infoSink.debug << "gl_FragCoord origin is upper left\n";
         if (earlyFragmentTests)
             infoSink.debug << "using early_fragment_tests\n";
+        if (postDepthCoverage)
+            infoSink.debug << "using post_depth_coverage\n";
         if (depthLayout != EldNone)
             infoSink.debug << "using " << TQualifier::getLayoutDepthString(depthLayout) << "\n";
         if (blendEquations != 0) {