diff --git a/src/Pipeline/BUILD.gn b/src/Pipeline/BUILD.gn
index e17084a..62f28cb 100644
--- a/src/Pipeline/BUILD.gn
+++ b/src/Pipeline/BUILD.gn
@@ -38,9 +38,10 @@
     "SamplerCore.cpp",
     "SetupRoutine.cpp",
     "ShaderCore.cpp",
-    "SpirvShader.cpp",
-    "SpirvShaderSampling.cpp",
     "SpirvShader_dbg.cpp",
+    "SpirvShader.cpp",
+    "SpirvShaderGLSLstd450.cpp",
+    "SpirvShaderSampling.cpp",
     "VertexProgram.cpp",
     "VertexRoutine.cpp",
   ]
diff --git a/src/Pipeline/SpirvShader.cpp b/src/Pipeline/SpirvShader.cpp
index 441ff43..ec916b5 100644
--- a/src/Pipeline/SpirvShader.cpp
+++ b/src/Pipeline/SpirvShader.cpp
@@ -33,8 +33,6 @@
 
 namespace
 {
-	constexpr float PI = 3.141592653589793f;
-
 	VkFormat SpirvFormatToVulkanFormat(spv::ImageFormat format)
 	{
 		switch (format)
@@ -3313,928 +3311,6 @@
 		return EmitResult::Continue;
 	}
 
-	SpirvShader::EmitResult SpirvShader::EmitExtendedInstruction(InsnIterator insn, EmitState *state) const
-	{
-		auto &type = getType(insn.word(1));
-		auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
-		auto extInstIndex = static_cast<GLSLstd450>(insn.word(4));
-
-		switch (extInstIndex)
-		{
-		case GLSLstd450FAbs:
-		{
-			auto src = GenericValue(this, state, insn.word(5));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, Abs(src.Float(i)));
-			}
-			break;
-		}
-		case GLSLstd450SAbs:
-		{
-			auto src = GenericValue(this, state, insn.word(5));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, Abs(src.Int(i)));
-			}
-			break;
-		}
-		case GLSLstd450Cross:
-		{
-			auto lhs = GenericValue(this, state, insn.word(5));
-			auto rhs = GenericValue(this, state, insn.word(6));
-			dst.move(0, lhs.Float(1) * rhs.Float(2) - rhs.Float(1) * lhs.Float(2));
-			dst.move(1, lhs.Float(2) * rhs.Float(0) - rhs.Float(2) * lhs.Float(0));
-			dst.move(2, lhs.Float(0) * rhs.Float(1) - rhs.Float(0) * lhs.Float(1));
-			break;
-		}
-		case GLSLstd450Floor:
-		{
-			auto src = GenericValue(this, state, insn.word(5));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, Floor(src.Float(i)));
-			}
-			break;
-		}
-		case GLSLstd450Trunc:
-		{
-			auto src = GenericValue(this, state, insn.word(5));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, Trunc(src.Float(i)));
-			}
-			break;
-		}
-		case GLSLstd450Ceil:
-		{
-			auto src = GenericValue(this, state, insn.word(5));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, Ceil(src.Float(i)));
-			}
-			break;
-		}
-		case GLSLstd450Fract:
-		{
-			auto src = GenericValue(this, state, insn.word(5));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, Frac(src.Float(i)));
-			}
-			break;
-		}
-		case GLSLstd450Round:
-		{
-			auto src = GenericValue(this, state, insn.word(5));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, Round(src.Float(i)));
-			}
-			break;
-		}
-		case GLSLstd450RoundEven:
-		{
-			auto src = GenericValue(this, state, insn.word(5));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				auto x = Round(src.Float(i));
-				// dst = round(src) + ((round(src) < src) * 2 - 1) * (fract(src) == 0.5) * isOdd(round(src));
-				dst.move(i, x + ((SIMD::Float(CmpLT(x, src.Float(i)) & SIMD::Int(1)) * SIMD::Float(2.0f)) - SIMD::Float(1.0f)) *
-						SIMD::Float(CmpEQ(Frac(src.Float(i)), SIMD::Float(0.5f)) & SIMD::Int(1)) * SIMD::Float(Int4(x) & SIMD::Int(1)));
-			}
-			break;
-		}
-		case GLSLstd450FMin:
-		{
-			auto lhs = GenericValue(this, state, insn.word(5));
-			auto rhs = GenericValue(this, state, insn.word(6));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, Min(lhs.Float(i), rhs.Float(i)));
-			}
-			break;
-		}
-		case GLSLstd450FMax:
-		{
-			auto lhs = GenericValue(this, state, insn.word(5));
-			auto rhs = GenericValue(this, state, insn.word(6));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, Max(lhs.Float(i), rhs.Float(i)));
-			}
-			break;
-		}
-		case GLSLstd450SMin:
-		{
-			auto lhs = GenericValue(this, state, insn.word(5));
-			auto rhs = GenericValue(this, state, insn.word(6));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, Min(lhs.Int(i), rhs.Int(i)));
-			}
-			break;
-		}
-		case GLSLstd450SMax:
-		{
-			auto lhs = GenericValue(this, state, insn.word(5));
-			auto rhs = GenericValue(this, state, insn.word(6));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, Max(lhs.Int(i), rhs.Int(i)));
-			}
-			break;
-		}
-		case GLSLstd450UMin:
-		{
-			auto lhs = GenericValue(this, state, insn.word(5));
-			auto rhs = GenericValue(this, state, insn.word(6));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, Min(lhs.UInt(i), rhs.UInt(i)));
-			}
-			break;
-		}
-		case GLSLstd450UMax:
-		{
-			auto lhs = GenericValue(this, state, insn.word(5));
-			auto rhs = GenericValue(this, state, insn.word(6));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, Max(lhs.UInt(i), rhs.UInt(i)));
-			}
-			break;
-		}
-		case GLSLstd450Step:
-		{
-			auto edge = GenericValue(this, state, insn.word(5));
-			auto x = GenericValue(this, state, insn.word(6));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, CmpNLT(x.Float(i), edge.Float(i)) & As<SIMD::Int>(SIMD::Float(1.0f)));
-			}
-			break;
-		}
-		case GLSLstd450SmoothStep:
-		{
-			auto edge0 = GenericValue(this, state, insn.word(5));
-			auto edge1 = GenericValue(this, state, insn.word(6));
-			auto x = GenericValue(this, state, insn.word(7));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				auto tx = Min(Max((x.Float(i) - edge0.Float(i)) /
-						(edge1.Float(i) - edge0.Float(i)), SIMD::Float(0.0f)), SIMD::Float(1.0f));
-				dst.move(i, tx * tx * (Float4(3.0f) - Float4(2.0f) * tx));
-			}
-			break;
-		}
-		case GLSLstd450FMix:
-		{
-			auto x = GenericValue(this, state, insn.word(5));
-			auto y = GenericValue(this, state, insn.word(6));
-			auto a = GenericValue(this, state, insn.word(7));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, a.Float(i) * (y.Float(i) - x.Float(i)) + x.Float(i));
-			}
-			break;
-		}
-		case GLSLstd450FClamp:
-		{
-			auto x = GenericValue(this, state, insn.word(5));
-			auto minVal = GenericValue(this, state, insn.word(6));
-			auto maxVal = GenericValue(this, state, insn.word(7));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, Min(Max(x.Float(i), minVal.Float(i)), maxVal.Float(i)));
-			}
-			break;
-		}
-		case GLSLstd450SClamp:
-		{
-			auto x = GenericValue(this, state, insn.word(5));
-			auto minVal = GenericValue(this, state, insn.word(6));
-			auto maxVal = GenericValue(this, state, insn.word(7));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, Min(Max(x.Int(i), minVal.Int(i)), maxVal.Int(i)));
-			}
-			break;
-		}
-		case GLSLstd450UClamp:
-		{
-			auto x = GenericValue(this, state, insn.word(5));
-			auto minVal = GenericValue(this, state, insn.word(6));
-			auto maxVal = GenericValue(this, state, insn.word(7));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, Min(Max(x.UInt(i), minVal.UInt(i)), maxVal.UInt(i)));
-			}
-			break;
-		}
-		case GLSLstd450FSign:
-		{
-			auto src = GenericValue(this, state, insn.word(5));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				auto neg = As<SIMD::Int>(CmpLT(src.Float(i), SIMD::Float(-0.0f))) & As<SIMD::Int>(SIMD::Float(-1.0f));
-				auto pos = As<SIMD::Int>(CmpNLE(src.Float(i), SIMD::Float(+0.0f))) & As<SIMD::Int>(SIMD::Float(1.0f));
-				dst.move(i, neg | pos);
-			}
-			break;
-		}
-		case GLSLstd450SSign:
-		{
-			auto src = GenericValue(this, state, insn.word(5));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				auto neg = CmpLT(src.Int(i), SIMD::Int(0)) & SIMD::Int(-1);
-				auto pos = CmpNLE(src.Int(i), SIMD::Int(0)) & SIMD::Int(1);
-				dst.move(i, neg | pos);
-			}
-			break;
-		}
-		case GLSLstd450Reflect:
-		{
-			auto I = GenericValue(this, state, insn.word(5));
-			auto N = GenericValue(this, state, insn.word(6));
-
-			SIMD::Float d = Dot(type.sizeInComponents, I, N);
-
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, I.Float(i) - SIMD::Float(2.0f) * d * N.Float(i));
-			}
-			break;
-		}
-		case GLSLstd450Refract:
-		{
-			auto I = GenericValue(this, state, insn.word(5));
-			auto N = GenericValue(this, state, insn.word(6));
-			auto eta = GenericValue(this, state, insn.word(7));
-
-			SIMD::Float d = Dot(type.sizeInComponents, I, N);
-			SIMD::Float k = SIMD::Float(1.0f) - eta.Float(0) * eta.Float(0) * (SIMD::Float(1.0f) - d * d);
-			SIMD::Int pos = CmpNLT(k, SIMD::Float(0.0f));
-			SIMD::Float t = (eta.Float(0) * d + Sqrt(k));
-
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, pos & As<SIMD::Int>(eta.Float(0) * I.Float(i) - t * N.Float(i)));
-			}
-			break;
-		}
-		case GLSLstd450FaceForward:
-		{
-			auto N = GenericValue(this, state, insn.word(5));
-			auto I = GenericValue(this, state, insn.word(6));
-			auto Nref = GenericValue(this, state, insn.word(7));
-
-			SIMD::Float d = Dot(type.sizeInComponents, I, Nref);
-			SIMD::Int neg = CmpLT(d, SIMD::Float(0.0f));
-
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				auto n = N.Float(i);
-				dst.move(i, (neg & As<SIMD::Int>(n)) | (~neg & As<SIMD::Int>(-n)));
-			}
-			break;
-		}
-		case GLSLstd450Length:
-		{
-			auto x = GenericValue(this, state, insn.word(5));
-			SIMD::Float d = Dot(getType(getObject(insn.word(5)).type).sizeInComponents, x, x);
-
-			dst.move(0, Sqrt(d));
-			break;
-		}
-		case GLSLstd450Normalize:
-		{
-			auto x = GenericValue(this, state, insn.word(5));
-			SIMD::Float d = Dot(getType(getObject(insn.word(5)).type).sizeInComponents, x, x);
-			SIMD::Float invLength = SIMD::Float(1.0f) / Sqrt(d);
-
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, invLength * x.Float(i));
-			}
-			break;
-		}
-		case GLSLstd450Distance:
-		{
-			auto p0 = GenericValue(this, state, insn.word(5));
-			auto p1 = GenericValue(this, state, insn.word(6));
-			auto p0Type = getType(p0.type);
-
-			// sqrt(dot(p0-p1, p0-p1))
-			SIMD::Float d = (p0.Float(0) - p1.Float(0)) * (p0.Float(0) - p1.Float(0));
-
-			for (auto i = 1u; i < p0Type.sizeInComponents; i++)
-			{
-				d += (p0.Float(i) - p1.Float(i)) * (p0.Float(i) - p1.Float(i));
-			}
-
-			dst.move(0, Sqrt(d));
-			break;
-		}
-		case GLSLstd450Modf:
-		{
-			auto val = GenericValue(this, state, insn.word(5));
-			auto ptrId = Object::ID(insn.word(6));
-			auto ptrTy = getType(getObject(ptrId).type);
-			auto ptr = GetPointerToData(ptrId, 0, state);
-			bool interleavedByLane = IsStorageInterleavedByLane(ptrTy.storageClass);
-			// TODO: GLSL modf() takes an output parameter and thus the pointer is assumed
-			// to be in bounds even for inactive lanes.
-			// - Clarify the SPIR-V spec.
-			// - Eliminate lane masking and assume interleaving.
-			auto robustness = OutOfBoundsBehavior::UndefinedBehavior;
-
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				SIMD::Float whole, frac;
-				std::tie(whole, frac) = Modf(val.Float(i));
-				dst.move(i, frac);
-				auto p = ptr + (i * sizeof(float));
-				if (interleavedByLane) { p = InterleaveByLane(p); }
-				p.Store(whole, robustness, state->activeLaneMask());
-			}
-			break;
-		}
-		case GLSLstd450ModfStruct:
-		{
-			auto val = GenericValue(this, state, insn.word(5));
-			auto valTy = getType(val.type);
-
-			for (auto i = 0u; i < valTy.sizeInComponents; i++)
-			{
-				SIMD::Float whole, frac;
-				std::tie(whole, frac) = Modf(val.Float(i));
-				dst.move(i, frac);
-				dst.move(i + valTy.sizeInComponents, whole);
-			}
-			break;
-		}
-		case GLSLstd450PackSnorm4x8:
-		{
-			auto val = GenericValue(this, state, insn.word(5));
-			dst.move(0, (SIMD::Int(Round(Min(Max(val.Float(0), SIMD::Float(-1.0f)), SIMD::Float(1.0f)) * SIMD::Float(127.0f))) &
-						 SIMD::Int(0xFF)) |
-						((SIMD::Int(Round(Min(Max(val.Float(1), SIMD::Float(-1.0f)), SIMD::Float(1.0f)) * SIMD::Float(127.0f))) &
-						  SIMD::Int(0xFF)) << 8) |
-						((SIMD::Int(Round(Min(Max(val.Float(2), SIMD::Float(-1.0f)), SIMD::Float(1.0f)) * SIMD::Float(127.0f))) &
-						  SIMD::Int(0xFF)) << 16) |
-						((SIMD::Int(Round(Min(Max(val.Float(3), SIMD::Float(-1.0f)), SIMD::Float(1.0f)) * SIMD::Float(127.0f))) &
-						  SIMD::Int(0xFF)) << 24));
-			break;
-		}
-		case GLSLstd450PackUnorm4x8:
-		{
-			auto val = GenericValue(this, state, insn.word(5));
-			dst.move(0, (SIMD::UInt(Round(Min(Max(val.Float(0), SIMD::Float(0.0f)), SIMD::Float(1.0f)) * SIMD::Float(255.0f)))) |
-						((SIMD::UInt(Round(Min(Max(val.Float(1), SIMD::Float(0.0f)), SIMD::Float(1.0f)) * SIMD::Float(255.0f)))) << 8) |
-						((SIMD::UInt(Round(Min(Max(val.Float(2), SIMD::Float(0.0f)), SIMD::Float(1.0f)) * SIMD::Float(255.0f)))) << 16) |
-						((SIMD::UInt(Round(Min(Max(val.Float(3), SIMD::Float(0.0f)), SIMD::Float(1.0f)) * SIMD::Float(255.0f)))) << 24));
-			break;
-		}
-		case GLSLstd450PackSnorm2x16:
-		{
-			auto val = GenericValue(this, state, insn.word(5));
-			dst.move(0, (SIMD::Int(Round(Min(Max(val.Float(0), SIMD::Float(-1.0f)), SIMD::Float(1.0f)) * SIMD::Float(32767.0f))) &
-						 SIMD::Int(0xFFFF)) |
-						((SIMD::Int(Round(Min(Max(val.Float(1), SIMD::Float(-1.0f)), SIMD::Float(1.0f)) * SIMD::Float(32767.0f))) &
-						  SIMD::Int(0xFFFF)) << 16));
-			break;
-		}
-		case GLSLstd450PackUnorm2x16:
-		{
-			auto val = GenericValue(this, state, insn.word(5));
-			dst.move(0, (SIMD::UInt(Round(Min(Max(val.Float(0), SIMD::Float(0.0f)), SIMD::Float(1.0f)) * SIMD::Float(65535.0f))) &
-						 SIMD::UInt(0xFFFF)) |
-						((SIMD::UInt(Round(Min(Max(val.Float(1), SIMD::Float(0.0f)), SIMD::Float(1.0f)) * SIMD::Float(65535.0f))) &
-						  SIMD::UInt(0xFFFF)) << 16));
-			break;
-		}
-		case GLSLstd450PackHalf2x16:
-		{
-			auto val = GenericValue(this, state, insn.word(5));
-			dst.move(0, FloatToHalfBits(val.UInt(0), false) | FloatToHalfBits(val.UInt(1), true));
-			break;
-		}
-		case GLSLstd450UnpackSnorm4x8:
-		{
-			auto val = GenericValue(this, state, insn.word(5));
-			dst.move(0, Min(Max(SIMD::Float(((val.Int(0)<<24) & SIMD::Int(0xFF000000))) * SIMD::Float(1.0f / float(0x7f000000)), SIMD::Float(-1.0f)), SIMD::Float(1.0f)));
-			dst.move(1, Min(Max(SIMD::Float(((val.Int(0)<<16) & SIMD::Int(0xFF000000))) * SIMD::Float(1.0f / float(0x7f000000)), SIMD::Float(-1.0f)), SIMD::Float(1.0f)));
-			dst.move(2, Min(Max(SIMD::Float(((val.Int(0)<<8) & SIMD::Int(0xFF000000))) * SIMD::Float(1.0f / float(0x7f000000)), SIMD::Float(-1.0f)), SIMD::Float(1.0f)));
-			dst.move(3, Min(Max(SIMD::Float(((val.Int(0)) & SIMD::Int(0xFF000000))) * SIMD::Float(1.0f / float(0x7f000000)), SIMD::Float(-1.0f)), SIMD::Float(1.0f)));
-			break;
-		}
-		case GLSLstd450UnpackUnorm4x8:
-		{
-			auto val = GenericValue(this, state, insn.word(5));
-			dst.move(0, SIMD::Float((val.UInt(0) & SIMD::UInt(0xFF))) * SIMD::Float(1.0f / 255.f));
-			dst.move(1, SIMD::Float(((val.UInt(0)>>8) & SIMD::UInt(0xFF))) * SIMD::Float(1.0f / 255.f));
-			dst.move(2, SIMD::Float(((val.UInt(0)>>16) & SIMD::UInt(0xFF))) * SIMD::Float(1.0f / 255.f));
-			dst.move(3, SIMD::Float(((val.UInt(0)>>24) & SIMD::UInt(0xFF))) * SIMD::Float(1.0f / 255.f));
-			break;
-		}
-		case GLSLstd450UnpackSnorm2x16:
-		{
-			auto val = GenericValue(this, state, insn.word(5));
-			// clamp(f / 32767.0, -1.0, 1.0)
-			dst.move(0, Min(Max(SIMD::Float(As<SIMD::Int>((val.UInt(0) & SIMD::UInt(0x0000FFFF)) << 16)) *
-								SIMD::Float(1.0f / float(0x7FFF0000)), SIMD::Float(-1.0f)), SIMD::Float(1.0f)));
-			dst.move(1, Min(Max(SIMD::Float(As<SIMD::Int>(val.UInt(0) & SIMD::UInt(0xFFFF0000))) * SIMD::Float(1.0f / float(0x7FFF0000)),
-								SIMD::Float(-1.0f)), SIMD::Float(1.0f)));
-			break;
-		}
-		case GLSLstd450UnpackUnorm2x16:
-		{
-			auto val = GenericValue(this, state, insn.word(5));
-			// f / 65535.0
-			dst.move(0, SIMD::Float((val.UInt(0) & SIMD::UInt(0x0000FFFF)) << 16) * SIMD::Float(1.0f / float(0xFFFF0000)));
-			dst.move(1, SIMD::Float(val.UInt(0) & SIMD::UInt(0xFFFF0000)) * SIMD::Float(1.0f / float(0xFFFF0000)));
-			break;
-		}
-		case GLSLstd450UnpackHalf2x16:
-		{
-			auto val = GenericValue(this, state, insn.word(5));
-			dst.move(0, halfToFloatBits(val.UInt(0) & SIMD::UInt(0x0000FFFF)));
-			dst.move(1, halfToFloatBits((val.UInt(0) & SIMD::UInt(0xFFFF0000)) >> 16));
-			break;
-		}
-		case GLSLstd450Fma:
-		{
-			auto a = GenericValue(this, state, insn.word(5));
-			auto b = GenericValue(this, state, insn.word(6));
-			auto c = GenericValue(this, state, insn.word(7));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, FMA(a.Float(i), b.Float(i), c.Float(i)));
-			}
-			break;
-		}
-		case GLSLstd450Frexp:
-		{
-			auto val = GenericValue(this, state, insn.word(5));
-			auto ptrId = Object::ID(insn.word(6));
-			auto ptrTy = getType(getObject(ptrId).type);
-			auto ptr = GetPointerToData(ptrId, 0, state);
-			bool interleavedByLane = IsStorageInterleavedByLane(ptrTy.storageClass);
-			// TODO: GLSL frexp() takes an output parameter and thus the pointer is assumed
-			// to be in bounds even for inactive lanes.
-			// - Clarify the SPIR-V spec.
-			// - Eliminate lane masking and assume interleaving.
-			auto robustness = OutOfBoundsBehavior::UndefinedBehavior;
-
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				SIMD::Float significand;
-				SIMD::Int exponent;
-				std::tie(significand, exponent) = Frexp(val.Float(i));
-
-				dst.move(i, significand);
-
-				auto p = ptr + (i * sizeof(float));
-				if (interleavedByLane) { p = InterleaveByLane(p); }
-				p.Store(exponent, robustness, state->activeLaneMask());
-			}
-			break;
-		}
-		case GLSLstd450FrexpStruct:
-		{
-			auto val = GenericValue(this, state, insn.word(5));
-			auto numComponents = getType(val.type).sizeInComponents;
-			for (auto i = 0u; i < numComponents; i++)
-			{
-				auto significandAndExponent = Frexp(val.Float(i));
-				dst.move(i, significandAndExponent.first);
-				dst.move(i + numComponents, significandAndExponent.second);
-			}
-			break;
-		}
-		case GLSLstd450Ldexp:
-		{
-			auto significand = GenericValue(this, state, insn.word(5));
-			auto exponent = GenericValue(this, state, insn.word(6));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				// Assumes IEEE 754
-				auto in = significand.Float(i);
-				auto significandExponent = Exponent(in);
-				auto combinedExponent = exponent.Int(i) + significandExponent;
-				auto isSignificandZero     = SIMD::UInt(CmpEQ(significand.Int(i), SIMD::Int(0)));
-				auto isSignificandInf      = SIMD::UInt(IsInf(in));
-				auto isSignificandNaN      = SIMD::UInt(IsNan(in));
-				auto isExponentNotTooSmall = SIMD::UInt(CmpGE(combinedExponent, SIMD::Int(-126)));
-				auto isExponentNotTooLarge = SIMD::UInt(CmpLE(combinedExponent, SIMD::Int(128)));
-				auto isExponentInBounds    = isExponentNotTooSmall & isExponentNotTooLarge;
-
-				SIMD::UInt v;
-				v  = significand.UInt(i) & SIMD::UInt(0x7FFFFF); // Add significand.
-				v |= (SIMD::UInt(combinedExponent + SIMD::Int(126)) << SIMD::UInt(23)); // Add exponent.
-				v &= isExponentInBounds; // Clear v if the exponent is OOB.
-
-				v |= significand.UInt(i) & SIMD::UInt(0x80000000); // Add sign bit.
-				v |= ~isExponentNotTooLarge & SIMD::UInt(0x7F800000); // Mark as inf if the exponent is too great.
-
-				// If the input significand is zero, inf or nan, just return the
-				// input significand.
-				auto passthrough = isSignificandZero | isSignificandInf | isSignificandNaN;
-				v = (v & ~passthrough) | (significand.UInt(i) & passthrough);
-
-				dst.move(i, As<SIMD::Float>(v));
-			}
-			break;
-		}
-		case GLSLstd450Radians:
-		{
-			auto degrees = GenericValue(this, state, insn.word(5));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, degrees.Float(i) * SIMD::Float(PI / 180.0f));
-			}
-			break;
-		}
-		case GLSLstd450Degrees:
-		{
-			auto radians = GenericValue(this, state, insn.word(5));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, radians.Float(i) * SIMD::Float(180.0f / PI));
-			}
-			break;
-		}
-		case GLSLstd450Sin:
-		{
-			auto radians = GenericValue(this, state, insn.word(5));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, Sin(radians.Float(i)));
-			}
-			break;
-		}
-		case GLSLstd450Cos:
-		{
-			auto radians = GenericValue(this, state, insn.word(5));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, Cos(radians.Float(i)));
-			}
-			break;
-		}
-		case GLSLstd450Tan:
-		{
-			auto radians = GenericValue(this, state, insn.word(5));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, Tan(radians.Float(i)));
-			}
-			break;
-		}
-		case GLSLstd450Asin:
-		{
-			auto val = GenericValue(this, state, insn.word(5));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, Asin(val.Float(i)));
-			}
-			break;
-		}
-		case GLSLstd450Acos:
-		{
-			auto val = GenericValue(this, state, insn.word(5));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, Acos(val.Float(i)));
-			}
-			break;
-		}
-		case GLSLstd450Atan:
-		{
-			auto val = GenericValue(this, state, insn.word(5));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, Atan(val.Float(i)));
-			}
-			break;
-		}
-		case GLSLstd450Sinh:
-		{
-			auto val = GenericValue(this, state, insn.word(5));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, Sinh(val.Float(i)));
-			}
-			break;
-		}
-		case GLSLstd450Cosh:
-		{
-			auto val = GenericValue(this, state, insn.word(5));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, Cosh(val.Float(i)));
-			}
-			break;
-		}
-		case GLSLstd450Tanh:
-		{
-			auto val = GenericValue(this, state, insn.word(5));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, Tanh(val.Float(i)));
-			}
-			break;
-		}
-		case GLSLstd450Asinh:
-		{
-			auto val = GenericValue(this, state, insn.word(5));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, Asinh(val.Float(i)));
-			}
-			break;
-		}
-		case GLSLstd450Acosh:
-		{
-			auto val = GenericValue(this, state, insn.word(5));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, Acosh(val.Float(i)));
-			}
-			break;
-		}
-		case GLSLstd450Atanh:
-		{
-			auto val = GenericValue(this, state, insn.word(5));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, Atanh(val.Float(i)));
-			}
-			break;
-		}
-		case GLSLstd450Atan2:
-		{
-			auto x = GenericValue(this, state, insn.word(5));
-			auto y = GenericValue(this, state, insn.word(6));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, Atan2(x.Float(i), y.Float(i)));
-			}
-			break;
-		}
-		case GLSLstd450Pow:
-		{
-			auto x = GenericValue(this, state, insn.word(5));
-			auto y = GenericValue(this, state, insn.word(6));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, Pow(x.Float(i), y.Float(i)));
-			}
-			break;
-		}
-		case GLSLstd450Exp:
-		{
-			auto val = GenericValue(this, state, insn.word(5));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, Exp(val.Float(i)));
-			}
-			break;
-		}
-		case GLSLstd450Log:
-		{
-			auto val = GenericValue(this, state, insn.word(5));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, Log(val.Float(i)));
-			}
-			break;
-		}
-		case GLSLstd450Exp2:
-		{
-			auto val = GenericValue(this, state, insn.word(5));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, Exp2(val.Float(i)));
-			}
-			break;
-		}
-		case GLSLstd450Log2:
-		{
-			auto val = GenericValue(this, state, insn.word(5));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, Log2(val.Float(i)));
-			}
-			break;
-		}
-		case GLSLstd450Sqrt:
-		{
-			auto val = GenericValue(this, state, insn.word(5));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, Sqrt(val.Float(i)));
-			}
-			break;
-		}
-		case GLSLstd450InverseSqrt:
-		{
-			auto val = GenericValue(this, state, insn.word(5));
-			Decorations d;
-			ApplyDecorationsForId(&d, insn.word(5));
-			if (d.RelaxedPrecision)
-			{
-				for (auto i = 0u; i < type.sizeInComponents; i++)
-				{
-					dst.move(i, RcpSqrt_pp(val.Float(i)));
-				}
-			}
-			else
-			{
-				for (auto i = 0u; i < type.sizeInComponents; i++)
-				{
-					dst.move(i, SIMD::Float(1.0f) / Sqrt(val.Float(i)));
-				}
-			}
-			break;
-		}
-		case GLSLstd450Determinant:
-		{
-			auto mat = GenericValue(this, state, insn.word(5));
-			auto numComponents = getType(mat.type).sizeInComponents;
-			switch (numComponents)
-			{
-			case 4: // 2x2
-				dst.move(0, Determinant(
-					mat.Float(0), mat.Float(1),
-					mat.Float(2), mat.Float(3)));
-				break;
-			case 9: // 3x3
-				dst.move(0, Determinant(
-					mat.Float(0), mat.Float(1), mat.Float(2),
-					mat.Float(3), mat.Float(4), mat.Float(5),
-					mat.Float(6), mat.Float(7), mat.Float(8)));
-				break;
-			case 16: // 4x4
-				dst.move(0, Determinant(
-					mat.Float(0),  mat.Float(1),  mat.Float(2),  mat.Float(3),
-					mat.Float(4),  mat.Float(5),  mat.Float(6),  mat.Float(7),
-					mat.Float(8),  mat.Float(9),  mat.Float(10), mat.Float(11),
-					mat.Float(12), mat.Float(13), mat.Float(14), mat.Float(15)));
-				break;
-			default:
-				UNREACHABLE("GLSLstd450Determinant can only operate with square matrices. Got %d elements", int(numComponents));
-			}
-			break;
-		}
-		case GLSLstd450MatrixInverse:
-		{
-			auto mat = GenericValue(this, state, insn.word(5));
-			auto numComponents = getType(mat.type).sizeInComponents;
-			switch (numComponents)
-			{
-			case 4: // 2x2
-			{
-				auto inv = MatrixInverse(
-					mat.Float(0), mat.Float(1),
-					mat.Float(2), mat.Float(3));
-				for (uint32_t i = 0; i < inv.size(); i++)
-				{
-					dst.move(i, inv[i]);
-				}
-				break;
-			}
-			case 9: // 3x3
-			{
-				auto inv = MatrixInverse(
-					mat.Float(0), mat.Float(1), mat.Float(2),
-					mat.Float(3), mat.Float(4), mat.Float(5),
-					mat.Float(6), mat.Float(7), mat.Float(8));
-				for (uint32_t i = 0; i < inv.size(); i++)
-				{
-					dst.move(i, inv[i]);
-				}
-				break;
-			}
-			case 16: // 4x4
-			{
-				auto inv = MatrixInverse(
-					mat.Float(0),  mat.Float(1),  mat.Float(2),  mat.Float(3),
-					mat.Float(4),  mat.Float(5),  mat.Float(6),  mat.Float(7),
-					mat.Float(8),  mat.Float(9),  mat.Float(10), mat.Float(11),
-					mat.Float(12), mat.Float(13), mat.Float(14), mat.Float(15));
-				for (uint32_t i = 0; i < inv.size(); i++)
-				{
-					dst.move(i, inv[i]);
-				}
-				break;
-			}
-			default:
-				UNREACHABLE("GLSLstd450MatrixInverse can only operate with square matrices. Got %d elements", int(numComponents));
-			}
-			break;
-		}
-		case GLSLstd450IMix:
-		{
-			UNREACHABLE("GLSLstd450IMix has been removed from the specification");
-			break;
-		}
-		case GLSLstd450PackDouble2x32:
-		{
-			UNSUPPORTED("SPIR-V Float64 Capability (GLSLstd450PackDouble2x32)");
-			break;
-		}
-		case GLSLstd450UnpackDouble2x32:
-		{
-			UNSUPPORTED("SPIR-V Float64 Capability (GLSLstd450UnpackDouble2x32)");
-			break;
-		}
-		case GLSLstd450FindILsb:
-		{
-			auto val = GenericValue(this, state, insn.word(5));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				auto v = val.UInt(i);
-				dst.move(i, Cttz(v, true) | CmpEQ(v, SIMD::UInt(0)));
-			}
-			break;
-		}
-		case GLSLstd450FindSMsb:
-		{
-			auto val = GenericValue(this, state, insn.word(5));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				auto v = val.UInt(i) ^ As<SIMD::UInt>(CmpLT(val.Int(i), SIMD::Int(0)));
-				dst.move(i, SIMD::UInt(31) - Ctlz(v, false));
-			}
-			break;
-		}
-		case GLSLstd450FindUMsb:
-		{
-			auto val = GenericValue(this, state, insn.word(5));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, SIMD::UInt(31) - Ctlz(val.UInt(i), false));
-			}
-			break;
-		}
-		case GLSLstd450InterpolateAtCentroid:
-		{
-			UNSUPPORTED("SPIR-V SampleRateShading Capability (GLSLstd450InterpolateAtCentroid)");
-			break;
-		}
-		case GLSLstd450InterpolateAtSample:
-		{
-			UNSUPPORTED("SPIR-V SampleRateShading Capability (GLSLstd450InterpolateAtCentroid)");
-			break;
-		}
-		case GLSLstd450InterpolateAtOffset:
-		{
-			UNSUPPORTED("SPIR-V SampleRateShading Capability (GLSLstd450InterpolateAtCentroid)");
-			break;
-		}
-		case GLSLstd450NMin:
-		{
-			auto x = GenericValue(this, state, insn.word(5));
-			auto y = GenericValue(this, state, insn.word(6));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, NMin(x.Float(i), y.Float(i)));
-			}
-			break;
-		}
-		case GLSLstd450NMax:
-		{
-			auto x = GenericValue(this, state, insn.word(5));
-			auto y = GenericValue(this, state, insn.word(6));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				dst.move(i, NMax(x.Float(i), y.Float(i)));
-			}
-			break;
-		}
-		case GLSLstd450NClamp:
-		{
-			auto x = GenericValue(this, state, insn.word(5));
-			auto minVal = GenericValue(this, state, insn.word(6));
-			auto maxVal = GenericValue(this, state, insn.word(7));
-			for (auto i = 0u; i < type.sizeInComponents; i++)
-			{
-				auto clamp = NMin(NMax(x.Float(i), minVal.Float(i)), maxVal.Float(i));
-				dst.move(i, clamp);
-			}
-			break;
-		}
-		default:
-			UNREACHABLE("ExtInst %d", int(extInstIndex));
-			break;
-		}
-
-		return EmitResult::Continue;
-	}
-
 	std::memory_order SpirvShader::MemoryOrder(spv::MemorySemanticsMask memorySemantics)
 	{
 		auto control = static_cast<uint32_t>(memorySemantics) & static_cast<uint32_t>(
diff --git a/src/Pipeline/SpirvShaderGLSLstd450.cpp b/src/Pipeline/SpirvShaderGLSLstd450.cpp
new file mode 100644
index 0000000..f9485ca
--- /dev/null
+++ b/src/Pipeline/SpirvShaderGLSLstd450.cpp
@@ -0,0 +1,951 @@
+// Copyright 2019 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "SpirvShader.hpp"
+
+#include "ShaderCore.hpp"
+
+#include <spirv/unified1/spirv.hpp>
+#include <spirv/unified1/GLSL.std.450.h>
+
+namespace
+{
+	constexpr float PI = 3.141592653589793f;
+}
+
+namespace sw {
+
+SpirvShader::EmitResult SpirvShader::EmitExtendedInstruction(InsnIterator insn, EmitState *state) const
+{
+	auto &type = getType(insn.word(1));
+	auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
+	auto extInstIndex = static_cast<GLSLstd450>(insn.word(4));
+
+	switch (extInstIndex)
+	{
+	case GLSLstd450FAbs:
+	{
+		auto src = GenericValue(this, state, insn.word(5));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, Abs(src.Float(i)));
+		}
+		break;
+	}
+	case GLSLstd450SAbs:
+	{
+		auto src = GenericValue(this, state, insn.word(5));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, Abs(src.Int(i)));
+		}
+		break;
+	}
+	case GLSLstd450Cross:
+	{
+		auto lhs = GenericValue(this, state, insn.word(5));
+		auto rhs = GenericValue(this, state, insn.word(6));
+		dst.move(0, lhs.Float(1) * rhs.Float(2) - rhs.Float(1) * lhs.Float(2));
+		dst.move(1, lhs.Float(2) * rhs.Float(0) - rhs.Float(2) * lhs.Float(0));
+		dst.move(2, lhs.Float(0) * rhs.Float(1) - rhs.Float(0) * lhs.Float(1));
+		break;
+	}
+	case GLSLstd450Floor:
+	{
+		auto src = GenericValue(this, state, insn.word(5));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, Floor(src.Float(i)));
+		}
+		break;
+	}
+	case GLSLstd450Trunc:
+	{
+		auto src = GenericValue(this, state, insn.word(5));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, Trunc(src.Float(i)));
+		}
+		break;
+	}
+	case GLSLstd450Ceil:
+	{
+		auto src = GenericValue(this, state, insn.word(5));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, Ceil(src.Float(i)));
+		}
+		break;
+	}
+	case GLSLstd450Fract:
+	{
+		auto src = GenericValue(this, state, insn.word(5));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, Frac(src.Float(i)));
+		}
+		break;
+	}
+	case GLSLstd450Round:
+	{
+		auto src = GenericValue(this, state, insn.word(5));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, Round(src.Float(i)));
+		}
+		break;
+	}
+	case GLSLstd450RoundEven:
+	{
+		auto src = GenericValue(this, state, insn.word(5));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			auto x = Round(src.Float(i));
+			// dst = round(src) + ((round(src) < src) * 2 - 1) * (fract(src) == 0.5) * isOdd(round(src));
+			dst.move(i, x + ((SIMD::Float(CmpLT(x, src.Float(i)) & SIMD::Int(1)) * SIMD::Float(2.0f)) - SIMD::Float(1.0f)) *
+					SIMD::Float(CmpEQ(Frac(src.Float(i)), SIMD::Float(0.5f)) & SIMD::Int(1)) * SIMD::Float(Int4(x) & SIMD::Int(1)));
+		}
+		break;
+	}
+	case GLSLstd450FMin:
+	{
+		auto lhs = GenericValue(this, state, insn.word(5));
+		auto rhs = GenericValue(this, state, insn.word(6));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, Min(lhs.Float(i), rhs.Float(i)));
+		}
+		break;
+	}
+	case GLSLstd450FMax:
+	{
+		auto lhs = GenericValue(this, state, insn.word(5));
+		auto rhs = GenericValue(this, state, insn.word(6));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, Max(lhs.Float(i), rhs.Float(i)));
+		}
+		break;
+	}
+	case GLSLstd450SMin:
+	{
+		auto lhs = GenericValue(this, state, insn.word(5));
+		auto rhs = GenericValue(this, state, insn.word(6));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, Min(lhs.Int(i), rhs.Int(i)));
+		}
+		break;
+	}
+	case GLSLstd450SMax:
+	{
+		auto lhs = GenericValue(this, state, insn.word(5));
+		auto rhs = GenericValue(this, state, insn.word(6));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, Max(lhs.Int(i), rhs.Int(i)));
+		}
+		break;
+	}
+	case GLSLstd450UMin:
+	{
+		auto lhs = GenericValue(this, state, insn.word(5));
+		auto rhs = GenericValue(this, state, insn.word(6));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, Min(lhs.UInt(i), rhs.UInt(i)));
+		}
+		break;
+	}
+	case GLSLstd450UMax:
+	{
+		auto lhs = GenericValue(this, state, insn.word(5));
+		auto rhs = GenericValue(this, state, insn.word(6));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, Max(lhs.UInt(i), rhs.UInt(i)));
+		}
+		break;
+	}
+	case GLSLstd450Step:
+	{
+		auto edge = GenericValue(this, state, insn.word(5));
+		auto x = GenericValue(this, state, insn.word(6));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, CmpNLT(x.Float(i), edge.Float(i)) & As<SIMD::Int>(SIMD::Float(1.0f)));
+		}
+		break;
+	}
+	case GLSLstd450SmoothStep:
+	{
+		auto edge0 = GenericValue(this, state, insn.word(5));
+		auto edge1 = GenericValue(this, state, insn.word(6));
+		auto x = GenericValue(this, state, insn.word(7));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			auto tx = Min(Max((x.Float(i) - edge0.Float(i)) /
+					(edge1.Float(i) - edge0.Float(i)), SIMD::Float(0.0f)), SIMD::Float(1.0f));
+			dst.move(i, tx * tx * (Float4(3.0f) - Float4(2.0f) * tx));
+		}
+		break;
+	}
+	case GLSLstd450FMix:
+	{
+		auto x = GenericValue(this, state, insn.word(5));
+		auto y = GenericValue(this, state, insn.word(6));
+		auto a = GenericValue(this, state, insn.word(7));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, a.Float(i) * (y.Float(i) - x.Float(i)) + x.Float(i));
+		}
+		break;
+	}
+	case GLSLstd450FClamp:
+	{
+		auto x = GenericValue(this, state, insn.word(5));
+		auto minVal = GenericValue(this, state, insn.word(6));
+		auto maxVal = GenericValue(this, state, insn.word(7));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, Min(Max(x.Float(i), minVal.Float(i)), maxVal.Float(i)));
+		}
+		break;
+	}
+	case GLSLstd450SClamp:
+	{
+		auto x = GenericValue(this, state, insn.word(5));
+		auto minVal = GenericValue(this, state, insn.word(6));
+		auto maxVal = GenericValue(this, state, insn.word(7));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, Min(Max(x.Int(i), minVal.Int(i)), maxVal.Int(i)));
+		}
+		break;
+	}
+	case GLSLstd450UClamp:
+	{
+		auto x = GenericValue(this, state, insn.word(5));
+		auto minVal = GenericValue(this, state, insn.word(6));
+		auto maxVal = GenericValue(this, state, insn.word(7));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, Min(Max(x.UInt(i), minVal.UInt(i)), maxVal.UInt(i)));
+		}
+		break;
+	}
+	case GLSLstd450FSign:
+	{
+		auto src = GenericValue(this, state, insn.word(5));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			auto neg = As<SIMD::Int>(CmpLT(src.Float(i), SIMD::Float(-0.0f))) & As<SIMD::Int>(SIMD::Float(-1.0f));
+			auto pos = As<SIMD::Int>(CmpNLE(src.Float(i), SIMD::Float(+0.0f))) & As<SIMD::Int>(SIMD::Float(1.0f));
+			dst.move(i, neg | pos);
+		}
+		break;
+	}
+	case GLSLstd450SSign:
+	{
+		auto src = GenericValue(this, state, insn.word(5));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			auto neg = CmpLT(src.Int(i), SIMD::Int(0)) & SIMD::Int(-1);
+			auto pos = CmpNLE(src.Int(i), SIMD::Int(0)) & SIMD::Int(1);
+			dst.move(i, neg | pos);
+		}
+		break;
+	}
+	case GLSLstd450Reflect:
+	{
+		auto I = GenericValue(this, state, insn.word(5));
+		auto N = GenericValue(this, state, insn.word(6));
+
+		SIMD::Float d = Dot(type.sizeInComponents, I, N);
+
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, I.Float(i) - SIMD::Float(2.0f) * d * N.Float(i));
+		}
+		break;
+	}
+	case GLSLstd450Refract:
+	{
+		auto I = GenericValue(this, state, insn.word(5));
+		auto N = GenericValue(this, state, insn.word(6));
+		auto eta = GenericValue(this, state, insn.word(7));
+
+		SIMD::Float d = Dot(type.sizeInComponents, I, N);
+		SIMD::Float k = SIMD::Float(1.0f) - eta.Float(0) * eta.Float(0) * (SIMD::Float(1.0f) - d * d);
+		SIMD::Int pos = CmpNLT(k, SIMD::Float(0.0f));
+		SIMD::Float t = (eta.Float(0) * d + Sqrt(k));
+
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, pos & As<SIMD::Int>(eta.Float(0) * I.Float(i) - t * N.Float(i)));
+		}
+		break;
+	}
+	case GLSLstd450FaceForward:
+	{
+		auto N = GenericValue(this, state, insn.word(5));
+		auto I = GenericValue(this, state, insn.word(6));
+		auto Nref = GenericValue(this, state, insn.word(7));
+
+		SIMD::Float d = Dot(type.sizeInComponents, I, Nref);
+		SIMD::Int neg = CmpLT(d, SIMD::Float(0.0f));
+
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			auto n = N.Float(i);
+			dst.move(i, (neg & As<SIMD::Int>(n)) | (~neg & As<SIMD::Int>(-n)));
+		}
+		break;
+	}
+	case GLSLstd450Length:
+	{
+		auto x = GenericValue(this, state, insn.word(5));
+		SIMD::Float d = Dot(getType(getObject(insn.word(5)).type).sizeInComponents, x, x);
+
+		dst.move(0, Sqrt(d));
+		break;
+	}
+	case GLSLstd450Normalize:
+	{
+		auto x = GenericValue(this, state, insn.word(5));
+		SIMD::Float d = Dot(getType(getObject(insn.word(5)).type).sizeInComponents, x, x);
+		SIMD::Float invLength = SIMD::Float(1.0f) / Sqrt(d);
+
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, invLength * x.Float(i));
+		}
+		break;
+	}
+	case GLSLstd450Distance:
+	{
+		auto p0 = GenericValue(this, state, insn.word(5));
+		auto p1 = GenericValue(this, state, insn.word(6));
+		auto p0Type = getType(p0.type);
+
+		// sqrt(dot(p0-p1, p0-p1))
+		SIMD::Float d = (p0.Float(0) - p1.Float(0)) * (p0.Float(0) - p1.Float(0));
+
+		for (auto i = 1u; i < p0Type.sizeInComponents; i++)
+		{
+			d += (p0.Float(i) - p1.Float(i)) * (p0.Float(i) - p1.Float(i));
+		}
+
+		dst.move(0, Sqrt(d));
+		break;
+	}
+	case GLSLstd450Modf:
+	{
+		auto val = GenericValue(this, state, insn.word(5));
+		auto ptrId = Object::ID(insn.word(6));
+		auto ptrTy = getType(getObject(ptrId).type);
+		auto ptr = GetPointerToData(ptrId, 0, state);
+		bool interleavedByLane = IsStorageInterleavedByLane(ptrTy.storageClass);
+		// TODO: GLSL modf() takes an output parameter and thus the pointer is assumed
+		// to be in bounds even for inactive lanes.
+		// - Clarify the SPIR-V spec.
+		// - Eliminate lane masking and assume interleaving.
+		auto robustness = OutOfBoundsBehavior::UndefinedBehavior;
+
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			SIMD::Float whole, frac;
+			std::tie(whole, frac) = Modf(val.Float(i));
+			dst.move(i, frac);
+			auto p = ptr + (i * sizeof(float));
+			if (interleavedByLane) { p = InterleaveByLane(p); }
+			p.Store(whole, robustness, state->activeLaneMask());
+		}
+		break;
+	}
+	case GLSLstd450ModfStruct:
+	{
+		auto val = GenericValue(this, state, insn.word(5));
+		auto valTy = getType(val.type);
+
+		for (auto i = 0u; i < valTy.sizeInComponents; i++)
+		{
+			SIMD::Float whole, frac;
+			std::tie(whole, frac) = Modf(val.Float(i));
+			dst.move(i, frac);
+			dst.move(i + valTy.sizeInComponents, whole);
+		}
+		break;
+	}
+	case GLSLstd450PackSnorm4x8:
+	{
+		auto val = GenericValue(this, state, insn.word(5));
+		dst.move(0, (SIMD::Int(Round(Min(Max(val.Float(0), SIMD::Float(-1.0f)), SIMD::Float(1.0f)) * SIMD::Float(127.0f))) &
+						SIMD::Int(0xFF)) |
+					((SIMD::Int(Round(Min(Max(val.Float(1), SIMD::Float(-1.0f)), SIMD::Float(1.0f)) * SIMD::Float(127.0f))) &
+						SIMD::Int(0xFF)) << 8) |
+					((SIMD::Int(Round(Min(Max(val.Float(2), SIMD::Float(-1.0f)), SIMD::Float(1.0f)) * SIMD::Float(127.0f))) &
+						SIMD::Int(0xFF)) << 16) |
+					((SIMD::Int(Round(Min(Max(val.Float(3), SIMD::Float(-1.0f)), SIMD::Float(1.0f)) * SIMD::Float(127.0f))) &
+						SIMD::Int(0xFF)) << 24));
+		break;
+	}
+	case GLSLstd450PackUnorm4x8:
+	{
+		auto val = GenericValue(this, state, insn.word(5));
+		dst.move(0, (SIMD::UInt(Round(Min(Max(val.Float(0), SIMD::Float(0.0f)), SIMD::Float(1.0f)) * SIMD::Float(255.0f)))) |
+					((SIMD::UInt(Round(Min(Max(val.Float(1), SIMD::Float(0.0f)), SIMD::Float(1.0f)) * SIMD::Float(255.0f)))) << 8) |
+					((SIMD::UInt(Round(Min(Max(val.Float(2), SIMD::Float(0.0f)), SIMD::Float(1.0f)) * SIMD::Float(255.0f)))) << 16) |
+					((SIMD::UInt(Round(Min(Max(val.Float(3), SIMD::Float(0.0f)), SIMD::Float(1.0f)) * SIMD::Float(255.0f)))) << 24));
+		break;
+	}
+	case GLSLstd450PackSnorm2x16:
+	{
+		auto val = GenericValue(this, state, insn.word(5));
+		dst.move(0, (SIMD::Int(Round(Min(Max(val.Float(0), SIMD::Float(-1.0f)), SIMD::Float(1.0f)) * SIMD::Float(32767.0f))) &
+						SIMD::Int(0xFFFF)) |
+					((SIMD::Int(Round(Min(Max(val.Float(1), SIMD::Float(-1.0f)), SIMD::Float(1.0f)) * SIMD::Float(32767.0f))) &
+						SIMD::Int(0xFFFF)) << 16));
+		break;
+	}
+	case GLSLstd450PackUnorm2x16:
+	{
+		auto val = GenericValue(this, state, insn.word(5));
+		dst.move(0, (SIMD::UInt(Round(Min(Max(val.Float(0), SIMD::Float(0.0f)), SIMD::Float(1.0f)) * SIMD::Float(65535.0f))) &
+						SIMD::UInt(0xFFFF)) |
+					((SIMD::UInt(Round(Min(Max(val.Float(1), SIMD::Float(0.0f)), SIMD::Float(1.0f)) * SIMD::Float(65535.0f))) &
+						SIMD::UInt(0xFFFF)) << 16));
+		break;
+	}
+	case GLSLstd450PackHalf2x16:
+	{
+		auto val = GenericValue(this, state, insn.word(5));
+		dst.move(0, FloatToHalfBits(val.UInt(0), false) | FloatToHalfBits(val.UInt(1), true));
+		break;
+	}
+	case GLSLstd450UnpackSnorm4x8:
+	{
+		auto val = GenericValue(this, state, insn.word(5));
+		dst.move(0, Min(Max(SIMD::Float(((val.Int(0)<<24) & SIMD::Int(0xFF000000))) * SIMD::Float(1.0f / float(0x7f000000)), SIMD::Float(-1.0f)), SIMD::Float(1.0f)));
+		dst.move(1, Min(Max(SIMD::Float(((val.Int(0)<<16) & SIMD::Int(0xFF000000))) * SIMD::Float(1.0f / float(0x7f000000)), SIMD::Float(-1.0f)), SIMD::Float(1.0f)));
+		dst.move(2, Min(Max(SIMD::Float(((val.Int(0)<<8) & SIMD::Int(0xFF000000))) * SIMD::Float(1.0f / float(0x7f000000)), SIMD::Float(-1.0f)), SIMD::Float(1.0f)));
+		dst.move(3, Min(Max(SIMD::Float(((val.Int(0)) & SIMD::Int(0xFF000000))) * SIMD::Float(1.0f / float(0x7f000000)), SIMD::Float(-1.0f)), SIMD::Float(1.0f)));
+		break;
+	}
+	case GLSLstd450UnpackUnorm4x8:
+	{
+		auto val = GenericValue(this, state, insn.word(5));
+		dst.move(0, SIMD::Float((val.UInt(0) & SIMD::UInt(0xFF))) * SIMD::Float(1.0f / 255.f));
+		dst.move(1, SIMD::Float(((val.UInt(0)>>8) & SIMD::UInt(0xFF))) * SIMD::Float(1.0f / 255.f));
+		dst.move(2, SIMD::Float(((val.UInt(0)>>16) & SIMD::UInt(0xFF))) * SIMD::Float(1.0f / 255.f));
+		dst.move(3, SIMD::Float(((val.UInt(0)>>24) & SIMD::UInt(0xFF))) * SIMD::Float(1.0f / 255.f));
+		break;
+	}
+	case GLSLstd450UnpackSnorm2x16:
+	{
+		auto val = GenericValue(this, state, insn.word(5));
+		// clamp(f / 32767.0, -1.0, 1.0)
+		dst.move(0, Min(Max(SIMD::Float(As<SIMD::Int>((val.UInt(0) & SIMD::UInt(0x0000FFFF)) << 16)) *
+							SIMD::Float(1.0f / float(0x7FFF0000)), SIMD::Float(-1.0f)), SIMD::Float(1.0f)));
+		dst.move(1, Min(Max(SIMD::Float(As<SIMD::Int>(val.UInt(0) & SIMD::UInt(0xFFFF0000))) * SIMD::Float(1.0f / float(0x7FFF0000)),
+							SIMD::Float(-1.0f)), SIMD::Float(1.0f)));
+		break;
+	}
+	case GLSLstd450UnpackUnorm2x16:
+	{
+		auto val = GenericValue(this, state, insn.word(5));
+		// f / 65535.0
+		dst.move(0, SIMD::Float((val.UInt(0) & SIMD::UInt(0x0000FFFF)) << 16) * SIMD::Float(1.0f / float(0xFFFF0000)));
+		dst.move(1, SIMD::Float(val.UInt(0) & SIMD::UInt(0xFFFF0000)) * SIMD::Float(1.0f / float(0xFFFF0000)));
+		break;
+	}
+	case GLSLstd450UnpackHalf2x16:
+	{
+		auto val = GenericValue(this, state, insn.word(5));
+		dst.move(0, halfToFloatBits(val.UInt(0) & SIMD::UInt(0x0000FFFF)));
+		dst.move(1, halfToFloatBits((val.UInt(0) & SIMD::UInt(0xFFFF0000)) >> 16));
+		break;
+	}
+	case GLSLstd450Fma:
+	{
+		auto a = GenericValue(this, state, insn.word(5));
+		auto b = GenericValue(this, state, insn.word(6));
+		auto c = GenericValue(this, state, insn.word(7));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, FMA(a.Float(i), b.Float(i), c.Float(i)));
+		}
+		break;
+	}
+	case GLSLstd450Frexp:
+	{
+		auto val = GenericValue(this, state, insn.word(5));
+		auto ptrId = Object::ID(insn.word(6));
+		auto ptrTy = getType(getObject(ptrId).type);
+		auto ptr = GetPointerToData(ptrId, 0, state);
+		bool interleavedByLane = IsStorageInterleavedByLane(ptrTy.storageClass);
+		// TODO: GLSL frexp() takes an output parameter and thus the pointer is assumed
+		// to be in bounds even for inactive lanes.
+		// - Clarify the SPIR-V spec.
+		// - Eliminate lane masking and assume interleaving.
+		auto robustness = OutOfBoundsBehavior::UndefinedBehavior;
+
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			SIMD::Float significand;
+			SIMD::Int exponent;
+			std::tie(significand, exponent) = Frexp(val.Float(i));
+
+			dst.move(i, significand);
+
+			auto p = ptr + (i * sizeof(float));
+			if (interleavedByLane) { p = InterleaveByLane(p); }
+			p.Store(exponent, robustness, state->activeLaneMask());
+		}
+		break;
+	}
+	case GLSLstd450FrexpStruct:
+	{
+		auto val = GenericValue(this, state, insn.word(5));
+		auto numComponents = getType(val.type).sizeInComponents;
+		for (auto i = 0u; i < numComponents; i++)
+		{
+			auto significandAndExponent = Frexp(val.Float(i));
+			dst.move(i, significandAndExponent.first);
+			dst.move(i + numComponents, significandAndExponent.second);
+		}
+		break;
+	}
+	case GLSLstd450Ldexp:
+	{
+		auto significand = GenericValue(this, state, insn.word(5));
+		auto exponent = GenericValue(this, state, insn.word(6));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			// Assumes IEEE 754
+			auto in = significand.Float(i);
+			auto significandExponent = Exponent(in);
+			auto combinedExponent = exponent.Int(i) + significandExponent;
+			auto isSignificandZero	 = SIMD::UInt(CmpEQ(significand.Int(i), SIMD::Int(0)));
+			auto isSignificandInf	  = SIMD::UInt(IsInf(in));
+			auto isSignificandNaN	  = SIMD::UInt(IsNan(in));
+			auto isExponentNotTooSmall = SIMD::UInt(CmpGE(combinedExponent, SIMD::Int(-126)));
+			auto isExponentNotTooLarge = SIMD::UInt(CmpLE(combinedExponent, SIMD::Int(128)));
+			auto isExponentInBounds	= isExponentNotTooSmall & isExponentNotTooLarge;
+
+			SIMD::UInt v;
+			v  = significand.UInt(i) & SIMD::UInt(0x7FFFFF); // Add significand.
+			v |= (SIMD::UInt(combinedExponent + SIMD::Int(126)) << SIMD::UInt(23)); // Add exponent.
+			v &= isExponentInBounds; // Clear v if the exponent is OOB.
+
+			v |= significand.UInt(i) & SIMD::UInt(0x80000000); // Add sign bit.
+			v |= ~isExponentNotTooLarge & SIMD::UInt(0x7F800000); // Mark as inf if the exponent is too great.
+
+			// If the input significand is zero, inf or nan, just return the
+			// input significand.
+			auto passthrough = isSignificandZero | isSignificandInf | isSignificandNaN;
+			v = (v & ~passthrough) | (significand.UInt(i) & passthrough);
+
+			dst.move(i, As<SIMD::Float>(v));
+		}
+		break;
+	}
+	case GLSLstd450Radians:
+	{
+		auto degrees = GenericValue(this, state, insn.word(5));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, degrees.Float(i) * SIMD::Float(PI / 180.0f));
+		}
+		break;
+	}
+	case GLSLstd450Degrees:
+	{
+		auto radians = GenericValue(this, state, insn.word(5));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, radians.Float(i) * SIMD::Float(180.0f / PI));
+		}
+		break;
+	}
+	case GLSLstd450Sin:
+	{
+		auto radians = GenericValue(this, state, insn.word(5));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, Sin(radians.Float(i)));
+		}
+		break;
+	}
+	case GLSLstd450Cos:
+	{
+		auto radians = GenericValue(this, state, insn.word(5));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, Cos(radians.Float(i)));
+		}
+		break;
+	}
+	case GLSLstd450Tan:
+	{
+		auto radians = GenericValue(this, state, insn.word(5));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, Tan(radians.Float(i)));
+		}
+		break;
+	}
+	case GLSLstd450Asin:
+	{
+		auto val = GenericValue(this, state, insn.word(5));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, Asin(val.Float(i)));
+		}
+		break;
+	}
+	case GLSLstd450Acos:
+	{
+		auto val = GenericValue(this, state, insn.word(5));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, Acos(val.Float(i)));
+		}
+		break;
+	}
+	case GLSLstd450Atan:
+	{
+		auto val = GenericValue(this, state, insn.word(5));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, Atan(val.Float(i)));
+		}
+		break;
+	}
+	case GLSLstd450Sinh:
+	{
+		auto val = GenericValue(this, state, insn.word(5));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, Sinh(val.Float(i)));
+		}
+		break;
+	}
+	case GLSLstd450Cosh:
+	{
+		auto val = GenericValue(this, state, insn.word(5));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, Cosh(val.Float(i)));
+		}
+		break;
+	}
+	case GLSLstd450Tanh:
+	{
+		auto val = GenericValue(this, state, insn.word(5));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, Tanh(val.Float(i)));
+		}
+		break;
+	}
+	case GLSLstd450Asinh:
+	{
+		auto val = GenericValue(this, state, insn.word(5));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, Asinh(val.Float(i)));
+		}
+		break;
+	}
+	case GLSLstd450Acosh:
+	{
+		auto val = GenericValue(this, state, insn.word(5));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, Acosh(val.Float(i)));
+		}
+		break;
+	}
+	case GLSLstd450Atanh:
+	{
+		auto val = GenericValue(this, state, insn.word(5));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, Atanh(val.Float(i)));
+		}
+		break;
+	}
+	case GLSLstd450Atan2:
+	{
+		auto x = GenericValue(this, state, insn.word(5));
+		auto y = GenericValue(this, state, insn.word(6));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, Atan2(x.Float(i), y.Float(i)));
+		}
+		break;
+	}
+	case GLSLstd450Pow:
+	{
+		auto x = GenericValue(this, state, insn.word(5));
+		auto y = GenericValue(this, state, insn.word(6));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, Pow(x.Float(i), y.Float(i)));
+		}
+		break;
+	}
+	case GLSLstd450Exp:
+	{
+		auto val = GenericValue(this, state, insn.word(5));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, Exp(val.Float(i)));
+		}
+		break;
+	}
+	case GLSLstd450Log:
+	{
+		auto val = GenericValue(this, state, insn.word(5));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, Log(val.Float(i)));
+		}
+		break;
+	}
+	case GLSLstd450Exp2:
+	{
+		auto val = GenericValue(this, state, insn.word(5));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, Exp2(val.Float(i)));
+		}
+		break;
+	}
+	case GLSLstd450Log2:
+	{
+		auto val = GenericValue(this, state, insn.word(5));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, Log2(val.Float(i)));
+		}
+		break;
+	}
+	case GLSLstd450Sqrt:
+	{
+		auto val = GenericValue(this, state, insn.word(5));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, Sqrt(val.Float(i)));
+		}
+		break;
+	}
+	case GLSLstd450InverseSqrt:
+	{
+		auto val = GenericValue(this, state, insn.word(5));
+		Decorations d;
+		ApplyDecorationsForId(&d, insn.word(5));
+		if (d.RelaxedPrecision)
+		{
+			for (auto i = 0u; i < type.sizeInComponents; i++)
+			{
+				dst.move(i, RcpSqrt_pp(val.Float(i)));
+			}
+		}
+		else
+		{
+			for (auto i = 0u; i < type.sizeInComponents; i++)
+			{
+				dst.move(i, SIMD::Float(1.0f) / Sqrt(val.Float(i)));
+			}
+		}
+		break;
+	}
+	case GLSLstd450Determinant:
+	{
+		auto mat = GenericValue(this, state, insn.word(5));
+		auto numComponents = getType(mat.type).sizeInComponents;
+		switch (numComponents)
+		{
+		case 4: // 2x2
+			dst.move(0, Determinant(
+				mat.Float(0), mat.Float(1),
+				mat.Float(2), mat.Float(3)));
+			break;
+		case 9: // 3x3
+			dst.move(0, Determinant(
+				mat.Float(0), mat.Float(1), mat.Float(2),
+				mat.Float(3), mat.Float(4), mat.Float(5),
+				mat.Float(6), mat.Float(7), mat.Float(8)));
+			break;
+		case 16: // 4x4
+			dst.move(0, Determinant(
+				mat.Float(0),  mat.Float(1),  mat.Float(2),  mat.Float(3),
+				mat.Float(4),  mat.Float(5),  mat.Float(6),  mat.Float(7),
+				mat.Float(8),  mat.Float(9),  mat.Float(10), mat.Float(11),
+				mat.Float(12), mat.Float(13), mat.Float(14), mat.Float(15)));
+			break;
+		default:
+			UNREACHABLE("GLSLstd450Determinant can only operate with square matrices. Got %d elements", int(numComponents));
+		}
+		break;
+	}
+	case GLSLstd450MatrixInverse:
+	{
+		auto mat = GenericValue(this, state, insn.word(5));
+		auto numComponents = getType(mat.type).sizeInComponents;
+		switch (numComponents)
+		{
+		case 4: // 2x2
+		{
+			auto inv = MatrixInverse(
+				mat.Float(0), mat.Float(1),
+				mat.Float(2), mat.Float(3));
+			for (uint32_t i = 0; i < inv.size(); i++)
+			{
+				dst.move(i, inv[i]);
+			}
+			break;
+		}
+		case 9: // 3x3
+		{
+			auto inv = MatrixInverse(
+				mat.Float(0), mat.Float(1), mat.Float(2),
+				mat.Float(3), mat.Float(4), mat.Float(5),
+				mat.Float(6), mat.Float(7), mat.Float(8));
+			for (uint32_t i = 0; i < inv.size(); i++)
+			{
+				dst.move(i, inv[i]);
+			}
+			break;
+		}
+		case 16: // 4x4
+		{
+			auto inv = MatrixInverse(
+				mat.Float(0),  mat.Float(1),  mat.Float(2),  mat.Float(3),
+				mat.Float(4),  mat.Float(5),  mat.Float(6),  mat.Float(7),
+				mat.Float(8),  mat.Float(9),  mat.Float(10), mat.Float(11),
+				mat.Float(12), mat.Float(13), mat.Float(14), mat.Float(15));
+			for (uint32_t i = 0; i < inv.size(); i++)
+			{
+				dst.move(i, inv[i]);
+			}
+			break;
+		}
+		default:
+			UNREACHABLE("GLSLstd450MatrixInverse can only operate with square matrices. Got %d elements", int(numComponents));
+		}
+		break;
+	}
+	case GLSLstd450IMix:
+	{
+		UNREACHABLE("GLSLstd450IMix has been removed from the specification");
+		break;
+	}
+	case GLSLstd450PackDouble2x32:
+	{
+		UNSUPPORTED("SPIR-V Float64 Capability (GLSLstd450PackDouble2x32)");
+		break;
+	}
+	case GLSLstd450UnpackDouble2x32:
+	{
+		UNSUPPORTED("SPIR-V Float64 Capability (GLSLstd450UnpackDouble2x32)");
+		break;
+	}
+	case GLSLstd450FindILsb:
+	{
+		auto val = GenericValue(this, state, insn.word(5));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			auto v = val.UInt(i);
+			dst.move(i, Cttz(v, true) | CmpEQ(v, SIMD::UInt(0)));
+		}
+		break;
+	}
+	case GLSLstd450FindSMsb:
+	{
+		auto val = GenericValue(this, state, insn.word(5));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			auto v = val.UInt(i) ^ As<SIMD::UInt>(CmpLT(val.Int(i), SIMD::Int(0)));
+			dst.move(i, SIMD::UInt(31) - Ctlz(v, false));
+		}
+		break;
+	}
+	case GLSLstd450FindUMsb:
+	{
+		auto val = GenericValue(this, state, insn.word(5));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, SIMD::UInt(31) - Ctlz(val.UInt(i), false));
+		}
+		break;
+	}
+	case GLSLstd450InterpolateAtCentroid:
+	{
+		UNSUPPORTED("SPIR-V SampleRateShading Capability (GLSLstd450InterpolateAtCentroid)");
+		break;
+	}
+	case GLSLstd450InterpolateAtSample:
+	{
+		UNSUPPORTED("SPIR-V SampleRateShading Capability (GLSLstd450InterpolateAtCentroid)");
+		break;
+	}
+	case GLSLstd450InterpolateAtOffset:
+	{
+		UNSUPPORTED("SPIR-V SampleRateShading Capability (GLSLstd450InterpolateAtCentroid)");
+		break;
+	}
+	case GLSLstd450NMin:
+	{
+		auto x = GenericValue(this, state, insn.word(5));
+		auto y = GenericValue(this, state, insn.word(6));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, NMin(x.Float(i), y.Float(i)));
+		}
+		break;
+	}
+	case GLSLstd450NMax:
+	{
+		auto x = GenericValue(this, state, insn.word(5));
+		auto y = GenericValue(this, state, insn.word(6));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			dst.move(i, NMax(x.Float(i), y.Float(i)));
+		}
+		break;
+	}
+	case GLSLstd450NClamp:
+	{
+		auto x = GenericValue(this, state, insn.word(5));
+		auto minVal = GenericValue(this, state, insn.word(6));
+		auto maxVal = GenericValue(this, state, insn.word(7));
+		for (auto i = 0u; i < type.sizeInComponents; i++)
+		{
+			auto clamp = NMin(NMax(x.Float(i), minVal.Float(i)), maxVal.Float(i));
+			dst.move(i, clamp);
+		}
+		break;
+	}
+	default:
+		UNREACHABLE("ExtInst %d", int(extInstIndex));
+		break;
+	}
+
+	return EmitResult::Continue;
+}
+
+}  // namespace sw
\ No newline at end of file
diff --git a/src/Vulkan/vulkan.vcxproj b/src/Vulkan/vulkan.vcxproj
index 7ee6982..3b6c30e 100644
--- a/src/Vulkan/vulkan.vcxproj
+++ b/src/Vulkan/vulkan.vcxproj
@@ -165,6 +165,7 @@
     <ClCompile Include="..\Pipeline\SetupRoutine.cpp" />
     <ClCompile Include="..\Pipeline\ShaderCore.cpp" />
     <ClCompile Include="..\Pipeline\SpirvShader.cpp" />
+    <ClCompile Include="..\Pipeline\SpirvShaderGLSLstd450.cpp" />
     <ClCompile Include="..\Pipeline\SpirvShaderSampling.cpp" />
     <ClCompile Include="..\Pipeline\SpirvShader_dbg.cpp" />
     <ClCompile Include="..\Pipeline\VertexProgram.cpp" />
diff --git a/src/Vulkan/vulkan.vcxproj.filters b/src/Vulkan/vulkan.vcxproj.filters
index 34ed4c7..7a0e176 100644
--- a/src/Vulkan/vulkan.vcxproj.filters
+++ b/src/Vulkan/vulkan.vcxproj.filters
@@ -246,6 +246,9 @@
     <ClCompile Include="..\Pipeline\SpirvShader.cpp">
       <Filter>Source Files\Pipeline</Filter>
     </ClCompile>
+    <ClCompile Include="..\Pipeline\SpirvShaderGLSLstd450.cpp">
+      <Filter>Source Files\Pipeline</Filter>
+    </ClCompile>
     <ClCompile Include="..\Pipeline\SpirvShaderSampling.cpp">
       <Filter>Source Files\Pipeline</Filter>
     </ClCompile>
