Rename GenericValue to Operand

Bug: b/129000021
Change-Id: I0000fc5e65bde87e9037400002db37cb6d50960d
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/43688
Presubmit-Ready: Nicolas Capens <nicolascapens@google.com>
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
diff --git a/src/Pipeline/SpirvShader.cpp b/src/Pipeline/SpirvShader.cpp
index 6327acf..0e47618 100644
--- a/src/Pipeline/SpirvShader.cpp
+++ b/src/Pipeline/SpirvShader.cpp
@@ -2009,7 +2009,7 @@
 		Object::ID srcObjectId = insn.word(3u + i);
 		auto &srcObject = getObject(srcObjectId);
 		auto &srcObjectTy = getType(srcObject.type);
-		GenericValue srcObjectAccess(this, state, srcObjectId);
+		Operand srcObjectAccess(this, state, srcObjectId);
 
 		for(auto j = 0u; j < srcObjectTy.sizeInComponents; j++)
 		{
@@ -2029,8 +2029,8 @@
 	auto &newPartObjectTy = getType(newPartObject.type);
 	auto firstNewComponent = WalkLiteralAccessChain(resultTypeId, insn.wordCount() - 5, insn.wordPointer(5));
 
-	GenericValue srcObjectAccess(this, state, insn.word(4));
-	GenericValue newPartObjectAccess(this, state, insn.word(3));
+	Operand srcObjectAccess(this, state, insn.word(4));
+	Operand newPartObjectAccess(this, state, insn.word(3));
 
 	// old components before
 	for(auto i = 0u; i < firstNewComponent; i++)
@@ -2059,7 +2059,7 @@
 	Type::ID compositeTypeId = compositeObject.definition.word(1);
 	auto firstComponent = WalkLiteralAccessChain(compositeTypeId, insn.wordCount() - 4, insn.wordPointer(4));
 
-	GenericValue compositeObjectAccess(this, state, insn.word(3));
+	Operand compositeObjectAccess(this, state, insn.word(3));
 	for(auto i = 0u; i < type.sizeInComponents; i++)
 	{
 		dst.move(i, compositeObjectAccess.Float(firstComponent + i));
@@ -2077,8 +2077,8 @@
 	// half type are all independent.
 	auto &firstHalfType = getType(getObject(insn.word(3)).type);
 
-	GenericValue firstHalfAccess(this, state, insn.word(3));
-	GenericValue secondHalfAccess(this, state, insn.word(4));
+	Operand firstHalfAccess(this, state, insn.word(3));
+	Operand secondHalfAccess(this, state, insn.word(4));
 
 	for(auto i = 0u; i < type.sizeInComponents; i++)
 	{
@@ -2108,8 +2108,8 @@
 	auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
 	auto &srcType = getType(getObject(insn.word(3)).type);
 
-	GenericValue src(this, state, insn.word(3));
-	GenericValue index(this, state, insn.word(4));
+	Operand src(this, state, insn.word(3));
+	Operand index(this, state, insn.word(4));
 
 	SIMD::UInt v = SIMD::UInt(0);
 
@@ -2127,9 +2127,9 @@
 	auto &type = getType(insn.word(1));
 	auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
 
-	GenericValue src(this, state, insn.word(3));
-	GenericValue component(this, state, insn.word(4));
-	GenericValue index(this, state, insn.word(5));
+	Operand src(this, state, insn.word(3));
+	Operand component(this, state, insn.word(4));
+	Operand index(this, state, insn.word(5));
 
 	for(auto i = 0u; i < type.sizeInComponents; i++)
 	{
@@ -2143,10 +2143,10 @@
 {
 	auto &type = getType(insn.word(1));
 	auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
-	auto cond = GenericValue(this, state, insn.word(3));
+	auto cond = Operand(this, state, insn.word(3));
 	auto condIsScalar = (getType(cond.type).sizeInComponents == 1);
-	auto lhs = GenericValue(this, state, insn.word(4));
-	auto rhs = GenericValue(this, state, insn.word(5));
+	auto lhs = Operand(this, state, insn.word(4));
+	auto rhs = Operand(this, state, insn.word(5));
 
 	for(auto i = 0u; i < type.sizeInComponents; i++)
 	{
@@ -2163,7 +2163,7 @@
 	ASSERT(type.sizeInComponents == 1);
 	auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
 	auto &srcType = getType(getObject(insn.word(3)).type);
-	auto src = GenericValue(this, state, insn.word(3));
+	auto src = Operand(this, state, insn.word(3));
 
 	SIMD::UInt result = src.UInt(0);
 
@@ -2182,7 +2182,7 @@
 	ASSERT(type.sizeInComponents == 1);
 	auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
 	auto &srcType = getType(getObject(insn.word(3)).type);
-	auto src = GenericValue(this, state, insn.word(3));
+	auto src = Operand(this, state, insn.word(3));
 
 	SIMD::UInt result = src.UInt(0);
 
@@ -2203,7 +2203,7 @@
 	auto memorySemantics = static_cast<spv::MemorySemanticsMask>(getObject(semanticsId).constantValue[0]);
 	auto memoryOrder = MemoryOrder(memorySemantics);
 	// Where no value is provided (increment/decrement) use an implicit value of 1.
-	auto value = (insn.wordCount() == 7) ? GenericValue(this, state, insn.word(6)).UInt(0) : RValue<SIMD::UInt>(1);
+	auto value = (insn.wordCount() == 7) ? Operand(this, state, insn.word(6)).UInt(0) : RValue<SIMD::UInt>(1);
 	auto &dst = state->createIntermediate(resultId, resultType.sizeInComponents);
 	auto ptr = state->getPointer(insn.word(3));
 	auto ptrOffsets = ptr.offsets();
@@ -2274,8 +2274,8 @@
 	auto memorySemanticsUnequal = static_cast<spv::MemorySemanticsMask>(getObject(insn.word(6)).constantValue[0]);
 	auto memoryOrderUnequal = MemoryOrder(memorySemanticsUnequal);
 
-	auto value = GenericValue(this, state, insn.word(7));
-	auto comparator = GenericValue(this, state, insn.word(8));
+	auto value = Operand(this, state, insn.word(7));
+	auto comparator = Operand(this, state, insn.word(8));
 	auto &dst = state->createIntermediate(resultId, resultType.sizeInComponents);
 	auto ptr = state->getPointer(insn.word(3));
 	auto ptrOffsets = ptr.offsets();
@@ -2302,7 +2302,7 @@
 {
 	auto ty = getType(insn.word(1));
 	auto &dst = state->createIntermediate(insn.word(2), ty.sizeInComponents);
-	auto src = GenericValue(this, state, insn.word(3));
+	auto src = Operand(this, state, insn.word(3));
 	for(uint32_t i = 0; i < ty.sizeInComponents; i++)
 	{
 		dst.move(i, src.Int(i));
@@ -2428,7 +2428,7 @@
 	}
 }
 
-SpirvShader::GenericValue::GenericValue(SpirvShader const *shader, EmitState const *state, SpirvShader::Object::ID objId)
+SpirvShader::Operand::Operand(SpirvShader const *shader, EmitState const *state, SpirvShader::Object::ID objId)
     : obj(shader->getObject(objId))
     , intermediate(obj.kind == SpirvShader::Object::Kind::Intermediate ? &state->getIntermediate(objId) : nullptr)
     , type(obj.type)
diff --git a/src/Pipeline/SpirvShader.hpp b/src/Pipeline/SpirvShader.hpp
index 27b37c6..6d38c46 100644
--- a/src/Pipeline/SpirvShader.hpp
+++ b/src/Pipeline/SpirvShader.hpp
@@ -961,13 +961,13 @@
 	// Constants are transparently widened to per-lane values in operator[].
 	// This is appropriate in most cases -- if we're not going to do something
 	// significantly different based on whether the value is uniform across lanes.
-	class GenericValue
+	class Operand
 	{
 		SpirvShader::Object const &obj;
 		Intermediate const *intermediate;
 
 	public:
-		GenericValue(SpirvShader const *shader, EmitState const *state, SpirvShader::Object::ID objId);
+		Operand(SpirvShader const *shader, EmitState const *state, SpirvShader::Object::ID objId);
 
 		RValue<SIMD::Float> Float(uint32_t i) const
 		{
@@ -1136,7 +1136,7 @@
 	EmitResult EmitArrayLength(InsnIterator insn, EmitState *state) const;
 
 	void GetImageDimensions(EmitState const *state, Type const &resultTy, Object::ID imageId, Object::ID lodId, Intermediate &dst) const;
-	SIMD::Pointer GetTexelAddress(EmitState const *state, SIMD::Pointer base, GenericValue const &coordinate, Type const &imageType, Pointer<Byte> descriptor, int texelSize, Object::ID sampleId, bool useStencilAspect) const;
+	SIMD::Pointer GetTexelAddress(EmitState const *state, SIMD::Pointer base, Operand const &coordinate, Type const &imageType, Pointer<Byte> descriptor, int texelSize, Object::ID sampleId, bool useStencilAspect) const;
 	uint32_t GetConstScalarInt(Object::ID id) const;
 	void EvalSpecConstantOp(InsnIterator insn);
 	void EvalSpecConstantUnaryOp(InsnIterator insn);
@@ -1168,7 +1168,7 @@
 	static bool IsStatement(spv::Op op);
 
 	// Helper as we often need to take dot products as part of doing other things.
-	SIMD::Float Dot(unsigned numComponents, GenericValue const &x, GenericValue const &y) const;
+	SIMD::Float Dot(unsigned numComponents, Operand const &x, Operand const &y) const;
 
 	// Splits x into a floating-point significand in the range [0.5, 1.0)
 	// and an integral exponent of two, such that:
diff --git a/src/Pipeline/SpirvShaderArithmetic.cpp b/src/Pipeline/SpirvShaderArithmetic.cpp
index f039124..a4c14f9 100644
--- a/src/Pipeline/SpirvShaderArithmetic.cpp
+++ b/src/Pipeline/SpirvShaderArithmetic.cpp
@@ -24,8 +24,8 @@
 {
 	auto &type = getType(insn.word(1));
 	auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
-	auto lhs = GenericValue(this, state, insn.word(3));
-	auto rhs = GenericValue(this, state, insn.word(4));
+	auto lhs = Operand(this, state, insn.word(3));
+	auto rhs = Operand(this, state, insn.word(4));
 
 	for(auto i = 0u; i < type.sizeInComponents; i++)
 	{
@@ -39,8 +39,8 @@
 {
 	auto &type = getType(insn.word(1));
 	auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
-	auto lhs = GenericValue(this, state, insn.word(3));
-	auto rhs = GenericValue(this, state, insn.word(4));
+	auto lhs = Operand(this, state, insn.word(3));
+	auto rhs = Operand(this, state, insn.word(4));
 	auto rhsType = getType(rhs.type);
 
 	for(auto i = 0u; i < type.sizeInComponents; i++)
@@ -60,8 +60,8 @@
 {
 	auto &type = getType(insn.word(1));
 	auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
-	auto lhs = GenericValue(this, state, insn.word(3));
-	auto rhs = GenericValue(this, state, insn.word(4));
+	auto lhs = Operand(this, state, insn.word(3));
+	auto rhs = Operand(this, state, insn.word(4));
 	auto lhsType = getType(lhs.type);
 
 	for(auto i = 0u; i < type.sizeInComponents; i++)
@@ -81,8 +81,8 @@
 {
 	auto &type = getType(insn.word(1));
 	auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
-	auto lhs = GenericValue(this, state, insn.word(3));
-	auto rhs = GenericValue(this, state, insn.word(4));
+	auto lhs = Operand(this, state, insn.word(3));
+	auto rhs = Operand(this, state, insn.word(4));
 
 	auto numColumns = type.definition.word(3);
 	auto numRows = getType(type.definition.word(2)).definition.word(3);
@@ -108,8 +108,8 @@
 {
 	auto &type = getType(insn.word(1));
 	auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
-	auto lhs = GenericValue(this, state, insn.word(3));
-	auto rhs = GenericValue(this, state, insn.word(4));
+	auto lhs = Operand(this, state, insn.word(3));
+	auto rhs = Operand(this, state, insn.word(4));
 	auto &lhsType = getType(lhs.type);
 	auto &rhsType = getType(rhs.type);
 
@@ -137,7 +137,7 @@
 {
 	auto &type = getType(insn.word(1));
 	auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
-	auto mat = GenericValue(this, state, insn.word(3));
+	auto mat = Operand(this, state, insn.word(3));
 
 	auto numCols = type.definition.word(3);
 	auto numRows = getType(type.definition.word(2)).sizeInComponents;
@@ -157,7 +157,7 @@
 {
 	auto &type = getType(insn.word(1));
 	auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
-	auto src = GenericValue(this, state, insn.word(3));
+	auto src = Operand(this, state, insn.word(3));
 
 	for(auto i = 0u; i < type.sizeInComponents; i++)
 	{
@@ -169,9 +169,9 @@
 				break;
 			case spv::OpBitFieldInsert:
 			{
-				auto insert = GenericValue(this, state, insn.word(4)).UInt(i);
-				auto offset = GenericValue(this, state, insn.word(5)).UInt(0);
-				auto count = GenericValue(this, state, insn.word(6)).UInt(0);
+				auto insert = Operand(this, state, insn.word(4)).UInt(i);
+				auto offset = Operand(this, state, insn.word(5)).UInt(0);
+				auto count = Operand(this, state, insn.word(6)).UInt(0);
 				auto one = SIMD::UInt(1);
 				auto v = src.UInt(i);
 				auto mask = Bitmask32(offset + count) ^ Bitmask32(offset);
@@ -181,8 +181,8 @@
 			case spv::OpBitFieldSExtract:
 			case spv::OpBitFieldUExtract:
 			{
-				auto offset = GenericValue(this, state, insn.word(4)).UInt(0);
-				auto count = GenericValue(this, state, insn.word(5)).UInt(0);
+				auto offset = Operand(this, state, insn.word(4)).UInt(0);
+				auto count = Operand(this, state, insn.word(5)).UInt(0);
 				auto one = SIMD::UInt(1);
 				auto v = src.UInt(i);
 				SIMD::UInt out = (v >> offset) & Bitmask32(count);
@@ -320,8 +320,8 @@
 	auto &type = getType(insn.word(1));
 	auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
 	auto &lhsType = getType(getObject(insn.word(3)).type);
-	auto lhs = GenericValue(this, state, insn.word(3));
-	auto rhs = GenericValue(this, state, insn.word(4));
+	auto lhs = Operand(this, state, insn.word(3));
+	auto rhs = Operand(this, state, insn.word(4));
 
 	for(auto i = 0u; i < lhsType.sizeInComponents; i++)
 	{
@@ -524,14 +524,14 @@
 	ASSERT(type.sizeInComponents == 1);
 	auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
 	auto &lhsType = getType(getObject(insn.word(3)).type);
-	auto lhs = GenericValue(this, state, insn.word(3));
-	auto rhs = GenericValue(this, state, insn.word(4));
+	auto lhs = Operand(this, state, insn.word(3));
+	auto rhs = Operand(this, state, insn.word(4));
 
 	dst.move(0, Dot(lhsType.sizeInComponents, lhs, rhs));
 	return EmitResult::Continue;
 }
 
-SIMD::Float SpirvShader::Dot(unsigned numComponents, GenericValue const &x, GenericValue const &y) const
+SIMD::Float SpirvShader::Dot(unsigned numComponents, Operand const &x, Operand const &y) const
 {
 	SIMD::Float d = x.Float(0) * y.Float(0);
 
diff --git a/src/Pipeline/SpirvShaderControlFlow.cpp b/src/Pipeline/SpirvShaderControlFlow.cpp
index 670dbfd..95b1e05 100644
--- a/src/Pipeline/SpirvShaderControlFlow.cpp
+++ b/src/Pipeline/SpirvShaderControlFlow.cpp
@@ -495,7 +495,7 @@
 	auto trueBlockId = Block::ID(block.branchInstruction.word(2));
 	auto falseBlockId = Block::ID(block.branchInstruction.word(3));
 
-	auto cond = GenericValue(this, state, condId);
+	auto cond = Operand(this, state, condId);
 	ASSERT_MSG(getType(cond.type).sizeInComponents == 1, "Condition must be a Boolean type scalar");
 
 	// TODO: Optimize for case where all lanes take same path.
@@ -514,7 +514,7 @@
 
 	auto selId = Object::ID(block.branchInstruction.word(1));
 
-	auto sel = GenericValue(this, state, selId);
+	auto sel = Operand(this, state, selId);
 	ASSERT_MSG(getType(sel.type).sizeInComponents == 1, "Selector must be a scalar");
 
 	auto numCases = (block.branchInstruction.wordCount() - 3) / 2;
@@ -678,7 +678,7 @@
 		}
 
 		auto mask = GetActiveLaneMaskEdge(state, blockId, currentBlock);
-		auto in = GenericValue(this, state, varId);
+		auto in = Operand(this, state, varId);
 
 		for(uint32_t i = 0; i < type.sizeInComponents; i++)
 		{
diff --git a/src/Pipeline/SpirvShaderDebugger.cpp b/src/Pipeline/SpirvShaderDebugger.cpp
index 41053de..0af1966 100644
--- a/src/Pipeline/SpirvShaderDebugger.cpp
+++ b/src/Pipeline/SpirvShaderDebugger.cpp
@@ -1203,7 +1203,7 @@
 				case Object::Kind::Constant:
 				case Object::Kind::Intermediate:
 				{
-					auto val = GenericValue(shader, state, id).Int(wordOffset);
+					auto val = Operand(shader, state, id).Int(wordOffset);
 
 					switch(ty->encoding)
 					{
@@ -1287,7 +1287,7 @@
 	}
 
 	// No debug type information. Derive from SPIR-V.
-	GenericValue val(shader, state, id);
+	Operand val(shader, state, id);
 	switch(shader->getType(val.type).opcode())
 	{
 		case spv::OpTypeInt:
diff --git a/src/Pipeline/SpirvShaderGLSLstd450.cpp b/src/Pipeline/SpirvShaderGLSLstd450.cpp
index 0b0de23..a6be75f 100644
--- a/src/Pipeline/SpirvShaderGLSLstd450.cpp
+++ b/src/Pipeline/SpirvShaderGLSLstd450.cpp
@@ -35,7 +35,7 @@
 	{
 		case GLSLstd450FAbs:
 		{
-			auto src = GenericValue(this, state, insn.word(5));
+			auto src = Operand(this, state, insn.word(5));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
 				dst.move(i, Abs(src.Float(i)));
@@ -44,7 +44,7 @@
 		}
 		case GLSLstd450SAbs:
 		{
-			auto src = GenericValue(this, state, insn.word(5));
+			auto src = Operand(this, state, insn.word(5));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
 				dst.move(i, Abs(src.Int(i)));
@@ -53,8 +53,8 @@
 		}
 		case GLSLstd450Cross:
 		{
-			auto lhs = GenericValue(this, state, insn.word(5));
-			auto rhs = GenericValue(this, state, insn.word(6));
+			auto lhs = Operand(this, state, insn.word(5));
+			auto rhs = Operand(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));
@@ -62,7 +62,7 @@
 		}
 		case GLSLstd450Floor:
 		{
-			auto src = GenericValue(this, state, insn.word(5));
+			auto src = Operand(this, state, insn.word(5));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
 				dst.move(i, Floor(src.Float(i)));
@@ -71,7 +71,7 @@
 		}
 		case GLSLstd450Trunc:
 		{
-			auto src = GenericValue(this, state, insn.word(5));
+			auto src = Operand(this, state, insn.word(5));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
 				dst.move(i, Trunc(src.Float(i)));
@@ -80,7 +80,7 @@
 		}
 		case GLSLstd450Ceil:
 		{
-			auto src = GenericValue(this, state, insn.word(5));
+			auto src = Operand(this, state, insn.word(5));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
 				dst.move(i, Ceil(src.Float(i)));
@@ -89,7 +89,7 @@
 		}
 		case GLSLstd450Fract:
 		{
-			auto src = GenericValue(this, state, insn.word(5));
+			auto src = Operand(this, state, insn.word(5));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
 				dst.move(i, Frac(src.Float(i)));
@@ -98,7 +98,7 @@
 		}
 		case GLSLstd450Round:
 		{
-			auto src = GenericValue(this, state, insn.word(5));
+			auto src = Operand(this, state, insn.word(5));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
 				dst.move(i, Round(src.Float(i)));
@@ -107,7 +107,7 @@
 		}
 		case GLSLstd450RoundEven:
 		{
-			auto src = GenericValue(this, state, insn.word(5));
+			auto src = Operand(this, state, insn.word(5));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
 				auto x = Round(src.Float(i));
@@ -119,8 +119,8 @@
 		}
 		case GLSLstd450FMin:
 		{
-			auto lhs = GenericValue(this, state, insn.word(5));
-			auto rhs = GenericValue(this, state, insn.word(6));
+			auto lhs = Operand(this, state, insn.word(5));
+			auto rhs = Operand(this, state, insn.word(6));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
 				dst.move(i, Min(lhs.Float(i), rhs.Float(i)));
@@ -129,8 +129,8 @@
 		}
 		case GLSLstd450FMax:
 		{
-			auto lhs = GenericValue(this, state, insn.word(5));
-			auto rhs = GenericValue(this, state, insn.word(6));
+			auto lhs = Operand(this, state, insn.word(5));
+			auto rhs = Operand(this, state, insn.word(6));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
 				dst.move(i, Max(lhs.Float(i), rhs.Float(i)));
@@ -139,8 +139,8 @@
 		}
 		case GLSLstd450SMin:
 		{
-			auto lhs = GenericValue(this, state, insn.word(5));
-			auto rhs = GenericValue(this, state, insn.word(6));
+			auto lhs = Operand(this, state, insn.word(5));
+			auto rhs = Operand(this, state, insn.word(6));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
 				dst.move(i, Min(lhs.Int(i), rhs.Int(i)));
@@ -149,8 +149,8 @@
 		}
 		case GLSLstd450SMax:
 		{
-			auto lhs = GenericValue(this, state, insn.word(5));
-			auto rhs = GenericValue(this, state, insn.word(6));
+			auto lhs = Operand(this, state, insn.word(5));
+			auto rhs = Operand(this, state, insn.word(6));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
 				dst.move(i, Max(lhs.Int(i), rhs.Int(i)));
@@ -159,8 +159,8 @@
 		}
 		case GLSLstd450UMin:
 		{
-			auto lhs = GenericValue(this, state, insn.word(5));
-			auto rhs = GenericValue(this, state, insn.word(6));
+			auto lhs = Operand(this, state, insn.word(5));
+			auto rhs = Operand(this, state, insn.word(6));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
 				dst.move(i, Min(lhs.UInt(i), rhs.UInt(i)));
@@ -169,8 +169,8 @@
 		}
 		case GLSLstd450UMax:
 		{
-			auto lhs = GenericValue(this, state, insn.word(5));
-			auto rhs = GenericValue(this, state, insn.word(6));
+			auto lhs = Operand(this, state, insn.word(5));
+			auto rhs = Operand(this, state, insn.word(6));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
 				dst.move(i, Max(lhs.UInt(i), rhs.UInt(i)));
@@ -179,8 +179,8 @@
 		}
 		case GLSLstd450Step:
 		{
-			auto edge = GenericValue(this, state, insn.word(5));
-			auto x = GenericValue(this, state, insn.word(6));
+			auto edge = Operand(this, state, insn.word(5));
+			auto x = Operand(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)));
@@ -189,9 +189,9 @@
 		}
 		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));
+			auto edge0 = Operand(this, state, insn.word(5));
+			auto edge1 = Operand(this, state, insn.word(6));
+			auto x = Operand(this, state, insn.word(7));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
 				auto tx = Min(Max((x.Float(i) - edge0.Float(i)) /
@@ -204,9 +204,9 @@
 		}
 		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));
+			auto x = Operand(this, state, insn.word(5));
+			auto y = Operand(this, state, insn.word(6));
+			auto a = Operand(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));
@@ -215,9 +215,9 @@
 		}
 		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));
+			auto x = Operand(this, state, insn.word(5));
+			auto minVal = Operand(this, state, insn.word(6));
+			auto maxVal = Operand(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)));
@@ -226,9 +226,9 @@
 		}
 		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));
+			auto x = Operand(this, state, insn.word(5));
+			auto minVal = Operand(this, state, insn.word(6));
+			auto maxVal = Operand(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)));
@@ -237,9 +237,9 @@
 		}
 		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));
+			auto x = Operand(this, state, insn.word(5));
+			auto minVal = Operand(this, state, insn.word(6));
+			auto maxVal = Operand(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)));
@@ -248,7 +248,7 @@
 		}
 		case GLSLstd450FSign:
 		{
-			auto src = GenericValue(this, state, insn.word(5));
+			auto src = Operand(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));
@@ -259,7 +259,7 @@
 		}
 		case GLSLstd450SSign:
 		{
-			auto src = GenericValue(this, state, insn.word(5));
+			auto src = Operand(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);
@@ -270,8 +270,8 @@
 		}
 		case GLSLstd450Reflect:
 		{
-			auto I = GenericValue(this, state, insn.word(5));
-			auto N = GenericValue(this, state, insn.word(6));
+			auto I = Operand(this, state, insn.word(5));
+			auto N = Operand(this, state, insn.word(6));
 
 			SIMD::Float d = Dot(type.sizeInComponents, I, N);
 
@@ -283,9 +283,9 @@
 		}
 		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));
+			auto I = Operand(this, state, insn.word(5));
+			auto N = Operand(this, state, insn.word(6));
+			auto eta = Operand(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);
@@ -300,9 +300,9 @@
 		}
 		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));
+			auto N = Operand(this, state, insn.word(5));
+			auto I = Operand(this, state, insn.word(6));
+			auto Nref = Operand(this, state, insn.word(7));
 
 			SIMD::Float d = Dot(type.sizeInComponents, I, Nref);
 			SIMD::Int neg = CmpLT(d, SIMD::Float(0.0f));
@@ -316,7 +316,7 @@
 		}
 		case GLSLstd450Length:
 		{
-			auto x = GenericValue(this, state, insn.word(5));
+			auto x = Operand(this, state, insn.word(5));
 			SIMD::Float d = Dot(getType(getObject(insn.word(5)).type).sizeInComponents, x, x);
 
 			dst.move(0, Sqrt(d));
@@ -324,7 +324,7 @@
 		}
 		case GLSLstd450Normalize:
 		{
-			auto x = GenericValue(this, state, insn.word(5));
+			auto x = Operand(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);
 
@@ -336,8 +336,8 @@
 		}
 		case GLSLstd450Distance:
 		{
-			auto p0 = GenericValue(this, state, insn.word(5));
-			auto p1 = GenericValue(this, state, insn.word(6));
+			auto p0 = Operand(this, state, insn.word(5));
+			auto p1 = Operand(this, state, insn.word(6));
 			auto p0Type = getType(p0.type);
 
 			// sqrt(dot(p0-p1, p0-p1))
@@ -353,7 +353,7 @@
 		}
 		case GLSLstd450Modf:
 		{
-			auto val = GenericValue(this, state, insn.word(5));
+			auto val = Operand(this, state, insn.word(5));
 			auto ptrId = Object::ID(insn.word(6));
 			auto ptrTy = getType(getObject(ptrId).type);
 			auto ptr = GetPointerToData(ptrId, 0, state);
@@ -377,7 +377,7 @@
 		}
 		case GLSLstd450ModfStruct:
 		{
-			auto val = GenericValue(this, state, insn.word(5));
+			auto val = Operand(this, state, insn.word(5));
 			auto valTy = getType(val.type);
 
 			for(auto i = 0u; i < valTy.sizeInComponents; i++)
@@ -391,7 +391,7 @@
 		}
 		case GLSLstd450PackSnorm4x8:
 		{
-			auto val = GenericValue(this, state, insn.word(5));
+			auto val = Operand(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))) &
@@ -407,7 +407,7 @@
 		}
 		case GLSLstd450PackUnorm4x8:
 		{
-			auto val = GenericValue(this, state, insn.word(5));
+			auto val = Operand(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) |
@@ -416,7 +416,7 @@
 		}
 		case GLSLstd450PackSnorm2x16:
 		{
-			auto val = GenericValue(this, state, insn.word(5));
+			auto val = Operand(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))) &
@@ -426,7 +426,7 @@
 		}
 		case GLSLstd450PackUnorm2x16:
 		{
-			auto val = GenericValue(this, state, insn.word(5));
+			auto val = Operand(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))) &
@@ -436,13 +436,13 @@
 		}
 		case GLSLstd450PackHalf2x16:
 		{
-			auto val = GenericValue(this, state, insn.word(5));
+			auto val = Operand(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));
+			auto val = Operand(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)));
@@ -451,7 +451,7 @@
 		}
 		case GLSLstd450UnpackUnorm4x8:
 		{
-			auto val = GenericValue(this, state, insn.word(5));
+			auto val = Operand(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));
@@ -460,7 +460,7 @@
 		}
 		case GLSLstd450UnpackSnorm2x16:
 		{
-			auto val = GenericValue(this, state, insn.word(5));
+			auto val = Operand(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)),
@@ -473,7 +473,7 @@
 		}
 		case GLSLstd450UnpackUnorm2x16:
 		{
-			auto val = GenericValue(this, state, insn.word(5));
+			auto val = Operand(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)));
@@ -481,16 +481,16 @@
 		}
 		case GLSLstd450UnpackHalf2x16:
 		{
-			auto val = GenericValue(this, state, insn.word(5));
+			auto val = Operand(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));
+			auto a = Operand(this, state, insn.word(5));
+			auto b = Operand(this, state, insn.word(6));
+			auto c = Operand(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)));
@@ -499,7 +499,7 @@
 		}
 		case GLSLstd450Frexp:
 		{
-			auto val = GenericValue(this, state, insn.word(5));
+			auto val = Operand(this, state, insn.word(5));
 			auto ptrId = Object::ID(insn.word(6));
 			auto ptrTy = getType(getObject(ptrId).type);
 			auto ptr = GetPointerToData(ptrId, 0, state);
@@ -526,7 +526,7 @@
 		}
 		case GLSLstd450FrexpStruct:
 		{
-			auto val = GenericValue(this, state, insn.word(5));
+			auto val = Operand(this, state, insn.word(5));
 			auto numComponents = getType(val.type).sizeInComponents;
 			for(auto i = 0u; i < numComponents; i++)
 			{
@@ -538,8 +538,8 @@
 		}
 		case GLSLstd450Ldexp:
 		{
-			auto significand = GenericValue(this, state, insn.word(5));
-			auto exponent = GenericValue(this, state, insn.word(6));
+			auto significand = Operand(this, state, insn.word(5));
+			auto exponent = Operand(this, state, insn.word(6));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
 				// Assumes IEEE 754
@@ -572,7 +572,7 @@
 		}
 		case GLSLstd450Radians:
 		{
-			auto degrees = GenericValue(this, state, insn.word(5));
+			auto degrees = Operand(this, state, insn.word(5));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
 				dst.move(i, degrees.Float(i) * SIMD::Float(PI / 180.0f));
@@ -581,7 +581,7 @@
 		}
 		case GLSLstd450Degrees:
 		{
-			auto radians = GenericValue(this, state, insn.word(5));
+			auto radians = Operand(this, state, insn.word(5));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
 				dst.move(i, radians.Float(i) * SIMD::Float(180.0f / PI));
@@ -590,7 +590,7 @@
 		}
 		case GLSLstd450Sin:
 		{
-			auto radians = GenericValue(this, state, insn.word(5));
+			auto radians = Operand(this, state, insn.word(5));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
 				dst.move(i, Sin(radians.Float(i)));
@@ -599,7 +599,7 @@
 		}
 		case GLSLstd450Cos:
 		{
-			auto radians = GenericValue(this, state, insn.word(5));
+			auto radians = Operand(this, state, insn.word(5));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
 				dst.move(i, Cos(radians.Float(i)));
@@ -608,7 +608,7 @@
 		}
 		case GLSLstd450Tan:
 		{
-			auto radians = GenericValue(this, state, insn.word(5));
+			auto radians = Operand(this, state, insn.word(5));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
 				dst.move(i, Tan(radians.Float(i)));
@@ -617,7 +617,7 @@
 		}
 		case GLSLstd450Asin:
 		{
-			auto val = GenericValue(this, state, insn.word(5));
+			auto val = Operand(this, state, insn.word(5));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
 				dst.move(i, Asin(val.Float(i)));
@@ -626,7 +626,7 @@
 		}
 		case GLSLstd450Acos:
 		{
-			auto val = GenericValue(this, state, insn.word(5));
+			auto val = Operand(this, state, insn.word(5));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
 				dst.move(i, Acos(val.Float(i)));
@@ -635,7 +635,7 @@
 		}
 		case GLSLstd450Atan:
 		{
-			auto val = GenericValue(this, state, insn.word(5));
+			auto val = Operand(this, state, insn.word(5));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
 				dst.move(i, Atan(val.Float(i)));
@@ -644,7 +644,7 @@
 		}
 		case GLSLstd450Sinh:
 		{
-			auto val = GenericValue(this, state, insn.word(5));
+			auto val = Operand(this, state, insn.word(5));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
 				dst.move(i, Sinh(val.Float(i)));
@@ -653,7 +653,7 @@
 		}
 		case GLSLstd450Cosh:
 		{
-			auto val = GenericValue(this, state, insn.word(5));
+			auto val = Operand(this, state, insn.word(5));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
 				dst.move(i, Cosh(val.Float(i)));
@@ -662,7 +662,7 @@
 		}
 		case GLSLstd450Tanh:
 		{
-			auto val = GenericValue(this, state, insn.word(5));
+			auto val = Operand(this, state, insn.word(5));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
 				dst.move(i, Tanh(val.Float(i)));
@@ -671,7 +671,7 @@
 		}
 		case GLSLstd450Asinh:
 		{
-			auto val = GenericValue(this, state, insn.word(5));
+			auto val = Operand(this, state, insn.word(5));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
 				dst.move(i, Asinh(val.Float(i)));
@@ -680,7 +680,7 @@
 		}
 		case GLSLstd450Acosh:
 		{
-			auto val = GenericValue(this, state, insn.word(5));
+			auto val = Operand(this, state, insn.word(5));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
 				dst.move(i, Acosh(val.Float(i)));
@@ -689,7 +689,7 @@
 		}
 		case GLSLstd450Atanh:
 		{
-			auto val = GenericValue(this, state, insn.word(5));
+			auto val = Operand(this, state, insn.word(5));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
 				dst.move(i, Atanh(val.Float(i)));
@@ -698,8 +698,8 @@
 		}
 		case GLSLstd450Atan2:
 		{
-			auto x = GenericValue(this, state, insn.word(5));
-			auto y = GenericValue(this, state, insn.word(6));
+			auto x = Operand(this, state, insn.word(5));
+			auto y = Operand(this, state, insn.word(6));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
 				dst.move(i, Atan2(x.Float(i), y.Float(i)));
@@ -708,8 +708,8 @@
 		}
 		case GLSLstd450Pow:
 		{
-			auto x = GenericValue(this, state, insn.word(5));
-			auto y = GenericValue(this, state, insn.word(6));
+			auto x = Operand(this, state, insn.word(5));
+			auto y = Operand(this, state, insn.word(6));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
 				dst.move(i, Pow(x.Float(i), y.Float(i)));
@@ -718,7 +718,7 @@
 		}
 		case GLSLstd450Exp:
 		{
-			auto val = GenericValue(this, state, insn.word(5));
+			auto val = Operand(this, state, insn.word(5));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
 				dst.move(i, Exp(val.Float(i)));
@@ -727,7 +727,7 @@
 		}
 		case GLSLstd450Log:
 		{
-			auto val = GenericValue(this, state, insn.word(5));
+			auto val = Operand(this, state, insn.word(5));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
 				dst.move(i, Log(val.Float(i)));
@@ -736,7 +736,7 @@
 		}
 		case GLSLstd450Exp2:
 		{
-			auto val = GenericValue(this, state, insn.word(5));
+			auto val = Operand(this, state, insn.word(5));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
 				dst.move(i, Exp2(val.Float(i)));
@@ -745,7 +745,7 @@
 		}
 		case GLSLstd450Log2:
 		{
-			auto val = GenericValue(this, state, insn.word(5));
+			auto val = Operand(this, state, insn.word(5));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
 				dst.move(i, Log2(val.Float(i)));
@@ -754,7 +754,7 @@
 		}
 		case GLSLstd450Sqrt:
 		{
-			auto val = GenericValue(this, state, insn.word(5));
+			auto val = Operand(this, state, insn.word(5));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
 				dst.move(i, Sqrt(val.Float(i)));
@@ -763,7 +763,7 @@
 		}
 		case GLSLstd450InverseSqrt:
 		{
-			auto val = GenericValue(this, state, insn.word(5));
+			auto val = Operand(this, state, insn.word(5));
 			Decorations d;
 			ApplyDecorationsForId(&d, insn.word(5));
 			if(d.RelaxedPrecision)
@@ -784,7 +784,7 @@
 		}
 		case GLSLstd450Determinant:
 		{
-			auto mat = GenericValue(this, state, insn.word(5));
+			auto mat = Operand(this, state, insn.word(5));
 			auto numComponents = getType(mat.type).sizeInComponents;
 			switch(numComponents)
 			{
@@ -813,7 +813,7 @@
 		}
 		case GLSLstd450MatrixInverse:
 		{
-			auto mat = GenericValue(this, state, insn.word(5));
+			auto mat = Operand(this, state, insn.word(5));
 			auto numComponents = getType(mat.type).sizeInComponents;
 			switch(numComponents)
 			{
@@ -875,7 +875,7 @@
 		}
 		case GLSLstd450FindILsb:
 		{
-			auto val = GenericValue(this, state, insn.word(5));
+			auto val = Operand(this, state, insn.word(5));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
 				auto v = val.UInt(i);
@@ -885,7 +885,7 @@
 		}
 		case GLSLstd450FindSMsb:
 		{
-			auto val = GenericValue(this, state, insn.word(5));
+			auto val = Operand(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)));
@@ -895,7 +895,7 @@
 		}
 		case GLSLstd450FindUMsb:
 		{
-			auto val = GenericValue(this, state, insn.word(5));
+			auto val = Operand(this, state, insn.word(5));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
 				dst.move(i, SIMD::UInt(31) - Ctlz(val.UInt(i), false));
@@ -919,8 +919,8 @@
 		}
 		case GLSLstd450NMin:
 		{
-			auto x = GenericValue(this, state, insn.word(5));
-			auto y = GenericValue(this, state, insn.word(6));
+			auto x = Operand(this, state, insn.word(5));
+			auto y = Operand(this, state, insn.word(6));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
 				dst.move(i, NMin(x.Float(i), y.Float(i)));
@@ -929,8 +929,8 @@
 		}
 		case GLSLstd450NMax:
 		{
-			auto x = GenericValue(this, state, insn.word(5));
-			auto y = GenericValue(this, state, insn.word(6));
+			auto x = Operand(this, state, insn.word(5));
+			auto y = Operand(this, state, insn.word(6));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
 				dst.move(i, NMax(x.Float(i), y.Float(i)));
@@ -939,9 +939,9 @@
 		}
 		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));
+			auto x = Operand(this, state, insn.word(5));
+			auto minVal = Operand(this, state, insn.word(6));
+			auto maxVal = Operand(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));
diff --git a/src/Pipeline/SpirvShaderGroup.cpp b/src/Pipeline/SpirvShaderGroup.cpp
index 2345ab9..ddbc7ca 100644
--- a/src/Pipeline/SpirvShaderGroup.cpp
+++ b/src/Pipeline/SpirvShaderGroup.cpp
@@ -34,7 +34,7 @@
 	    const I identityValue,
 	    APPLY &&apply)
 	{
-		SpirvShader::GenericValue value(shader, state, insn.word(5));
+		SpirvShader::Operand value(shader, state, insn.word(5));
 		auto &type = shader->getType(SpirvShader::Type::ID(insn.word(1)));
 		for(auto i = 0u; i < type.sizeInComponents; i++)
 		{
@@ -104,21 +104,21 @@
 
 		case spv::OpGroupNonUniformAll:
 		{
-			GenericValue predicate(this, state, insn.word(4));
+			Operand predicate(this, state, insn.word(4));
 			dst.move(0, AndAll(predicate.UInt(0) | ~As<SIMD::UInt>(state->activeLaneMask())));
 			break;
 		}
 
 		case spv::OpGroupNonUniformAny:
 		{
-			GenericValue predicate(this, state, insn.word(4));
+			Operand predicate(this, state, insn.word(4));
 			dst.move(0, OrAll(predicate.UInt(0) & As<SIMD::UInt>(state->activeLaneMask())));
 			break;
 		}
 
 		case spv::OpGroupNonUniformAllEqual:
 		{
-			GenericValue value(this, state, insn.word(4));
+			Operand value(this, state, insn.word(4));
 			auto res = SIMD::UInt(0xffffffff);
 			SIMD::UInt active = As<SIMD::UInt>(state->activeLaneMask());
 			SIMD::UInt inactive = ~active;
@@ -140,7 +140,7 @@
 		{
 			auto valueId = Object::ID(insn.word(4));
 			auto id = SIMD::Int(GetConstScalarInt(insn.word(5)));
-			GenericValue value(this, state, valueId);
+			Operand value(this, state, valueId);
 			auto mask = CmpEQ(id, SIMD::Int(0, 1, 2, 3));
 			for(auto i = 0u; i < type.sizeInComponents; i++)
 			{
@@ -152,7 +152,7 @@
 		case spv::OpGroupNonUniformBroadcastFirst:
 		{
 			auto valueId = Object::ID(insn.word(4));
-			GenericValue value(this, state, valueId);
+			Operand value(this, state, valueId);
 			// Result is true only in the active invocation with the lowest id
 			// in the group, otherwise result is false.
 			SIMD::Int active = state->activeLaneMask();
@@ -170,7 +170,7 @@
 		case spv::OpGroupNonUniformBallot:
 		{
 			ASSERT(type.sizeInComponents == 4);
-			GenericValue predicate(this, state, insn.word(4));
+			Operand predicate(this, state, insn.word(4));
 			dst.move(0, SIMD::Int(SignMask(state->activeLaneMask() & predicate.Int(0))));
 			dst.move(1, SIMD::Int(0));
 			dst.move(2, SIMD::Int(0));
@@ -183,7 +183,7 @@
 			auto valueId = Object::ID(insn.word(4));
 			ASSERT(type.sizeInComponents == 1);
 			ASSERT(getType(getObject(valueId).type).sizeInComponents == 4);
-			GenericValue value(this, state, valueId);
+			Operand value(this, state, valueId);
 			auto bit = (value.Int(0) >> SIMD::Int(0, 1, 2, 3)) & SIMD::Int(1);
 			dst.move(0, -bit);
 			break;
@@ -196,8 +196,8 @@
 			ASSERT(type.sizeInComponents == 1);
 			ASSERT(getType(getObject(valueId).type).sizeInComponents == 4);
 			ASSERT(getType(getObject(indexId).type).sizeInComponents == 1);
-			GenericValue value(this, state, valueId);
-			GenericValue index(this, state, indexId);
+			Operand value(this, state, valueId);
+			Operand index(this, state, indexId);
 			auto vecIdx = index.Int(0) / SIMD::Int(32);
 			auto bitIdx = index.Int(0) & SIMD::Int(31);
 			auto bits = (value.Int(0) & CmpEQ(vecIdx, SIMD::Int(0))) |
@@ -214,7 +214,7 @@
 			auto valueId = Object::ID(insn.word(5));
 			ASSERT(type.sizeInComponents == 1);
 			ASSERT(getType(getObject(valueId).type).sizeInComponents == 4);
-			GenericValue value(this, state, valueId);
+			Operand value(this, state, valueId);
 			switch(operation)
 			{
 				case spv::GroupOperationReduce:
@@ -237,7 +237,7 @@
 			auto valueId = Object::ID(insn.word(4));
 			ASSERT(type.sizeInComponents == 1);
 			ASSERT(getType(getObject(valueId).type).sizeInComponents == 4);
-			GenericValue value(this, state, valueId);
+			Operand value(this, state, valueId);
 			dst.move(0, Cttz(value.UInt(0) & SIMD::UInt(15), true));
 			break;
 		}
@@ -247,15 +247,15 @@
 			auto valueId = Object::ID(insn.word(4));
 			ASSERT(type.sizeInComponents == 1);
 			ASSERT(getType(getObject(valueId).type).sizeInComponents == 4);
-			GenericValue value(this, state, valueId);
+			Operand value(this, state, valueId);
 			dst.move(0, SIMD::UInt(31) - Ctlz(value.UInt(0) & SIMD::UInt(15), false));
 			break;
 		}
 
 		case spv::OpGroupNonUniformShuffle:
 		{
-			GenericValue value(this, state, insn.word(4));
-			GenericValue id(this, state, insn.word(5));
+			Operand value(this, state, insn.word(4));
+			Operand id(this, state, insn.word(5));
 			auto x = CmpEQ(SIMD::Int(0), id.Int(0));
 			auto y = CmpEQ(SIMD::Int(1), id.Int(0));
 			auto z = CmpEQ(SIMD::Int(2), id.Int(0));
@@ -270,8 +270,8 @@
 
 		case spv::OpGroupNonUniformShuffleXor:
 		{
-			GenericValue value(this, state, insn.word(4));
-			GenericValue mask(this, state, insn.word(5));
+			Operand value(this, state, insn.word(4));
+			Operand mask(this, state, insn.word(5));
 			auto x = CmpEQ(SIMD::Int(0), SIMD::Int(0, 1, 2, 3) ^ mask.Int(0));
 			auto y = CmpEQ(SIMD::Int(1), SIMD::Int(0, 1, 2, 3) ^ mask.Int(0));
 			auto z = CmpEQ(SIMD::Int(2), SIMD::Int(0, 1, 2, 3) ^ mask.Int(0));
@@ -286,8 +286,8 @@
 
 		case spv::OpGroupNonUniformShuffleUp:
 		{
-			GenericValue value(this, state, insn.word(4));
-			GenericValue delta(this, state, insn.word(5));
+			Operand value(this, state, insn.word(4));
+			Operand delta(this, state, insn.word(5));
 			auto d0 = CmpEQ(SIMD::Int(0), delta.Int(0));
 			auto d1 = CmpEQ(SIMD::Int(1), delta.Int(0));
 			auto d2 = CmpEQ(SIMD::Int(2), delta.Int(0));
@@ -302,8 +302,8 @@
 
 		case spv::OpGroupNonUniformShuffleDown:
 		{
-			GenericValue value(this, state, insn.word(4));
-			GenericValue delta(this, state, insn.word(5));
+			Operand value(this, state, insn.word(4));
+			Operand delta(this, state, insn.word(5));
 			auto d0 = CmpEQ(SIMD::Int(0), delta.Int(0));
 			auto d1 = CmpEQ(SIMD::Int(1), delta.Int(0));
 			auto d2 = CmpEQ(SIMD::Int(2), delta.Int(0));
diff --git a/src/Pipeline/SpirvShaderImage.cpp b/src/Pipeline/SpirvShaderImage.cpp
index ed3c8ba..eb20f48 100644
--- a/src/Pipeline/SpirvShaderImage.cpp
+++ b/src/Pipeline/SpirvShaderImage.cpp
@@ -120,7 +120,7 @@
 	auto &sampledImage = getObject(sampledImageId);
 	auto samplerDescriptor = (sampledImage.opcode() == spv::OpSampledImage) ? state->getPointer(sampledImage.definition.word(4)).base : imageDescriptor;
 
-	auto coordinate = GenericValue(this, state, coordinateId);
+	auto coordinate = Operand(this, state, coordinateId);
 	auto &coordinateType = getType(coordinate.type);
 
 	Pointer<Byte> sampler = samplerDescriptor + OFFSET(vk::SampledImageDescriptor, sampler);  // vk::Sampler*
@@ -224,7 +224,7 @@
 
 	if(instruction.isDref())
 	{
-		auto drefValue = GenericValue(this, state, insn.word(5));
+		auto drefValue = Operand(this, state, insn.word(5));
 
 		if(instruction.isProj())
 		{
@@ -240,14 +240,14 @@
 
 	if(lodOrBias)
 	{
-		auto lodValue = GenericValue(this, state, lodOrBiasId);
+		auto lodValue = Operand(this, state, lodOrBiasId);
 		in[i] = lodValue.Float(0);
 		i++;
 	}
 	else if(grad)
 	{
-		auto dxValue = GenericValue(this, state, gradDxId);
-		auto dyValue = GenericValue(this, state, gradDyId);
+		auto dxValue = Operand(this, state, gradDxId);
+		auto dyValue = Operand(this, state, gradDyId);
 		auto &dxyType = getType(dxValue.type);
 		ASSERT(dxyType.sizeInComponents == getType(dyValue.type).sizeInComponents);
 
@@ -274,7 +274,7 @@
 
 	if(constOffset)
 	{
-		auto offsetValue = GenericValue(this, state, offsetId);
+		auto offsetValue = Operand(this, state, offsetId);
 		auto &offsetType = getType(offsetValue.type);
 
 		instruction.offset = offsetType.sizeInComponents;
@@ -287,7 +287,7 @@
 
 	if(sample)
 	{
-		auto sampleValue = GenericValue(this, state, sampleId);
+		auto sampleValue = Operand(this, state, sampleId);
 		in[i] = As<SIMD::Float>(sampleValue.Int(0));
 	}
 
@@ -386,7 +386,7 @@
 	std::vector<Int> out;
 	if(lodId != 0)
 	{
-		auto lodVal = GenericValue(this, state, lodId);
+		auto lodVal = Operand(this, state, lodId);
 		ASSERT(getType(lodVal.type).sizeInComponents == 1);
 		auto lod = lodVal.Int(0);
 		auto one = SIMD::Int(1);
@@ -477,7 +477,7 @@
 	return EmitResult::Continue;
 }
 
-SIMD::Pointer SpirvShader::GetTexelAddress(EmitState const *state, SIMD::Pointer ptr, GenericValue const &coordinate, Type const &imageType, Pointer<Byte> descriptor, int texelSize, Object::ID sampleId, bool useStencilAspect) const
+SIMD::Pointer SpirvShader::GetTexelAddress(EmitState const *state, SIMD::Pointer ptr, Operand const &coordinate, Type const &imageType, Pointer<Byte> descriptor, int texelSize, Object::ID sampleId, bool useStencilAspect) const
 {
 	auto routine = state->routine;
 	bool isArrayed = imageType.definition.word(5) != 0;
@@ -532,7 +532,7 @@
 
 	if(sampleId.value())
 	{
-		GenericValue sample(this, state, sampleId);
+		Operand sample(this, state, sampleId);
 		ptr += sample.Int(0) * samplePitch;
 	}
 
@@ -566,7 +566,7 @@
 	ASSERT(imageType.definition.opcode() == spv::OpTypeImage);
 	auto dim = static_cast<spv::Dim>(imageType.definition.word(3));
 
-	auto coordinate = GenericValue(this, state, insn.word(4));
+	auto coordinate = Operand(this, state, insn.word(4));
 	const DescriptorDecorations &d = descriptorDecorations.at(imageId);
 
 	// For subpass data, format in the instruction is spv::ImageFormatUnknown. Get it from
@@ -855,8 +855,8 @@
 	// TODO(b/131171141): Not handling any image operands yet.
 	ASSERT(insn.wordCount() == 4);
 
-	auto coordinate = GenericValue(this, state, insn.word(2));
-	auto texel = GenericValue(this, state, insn.word(3));
+	auto coordinate = Operand(this, state, insn.word(2));
+	auto texel = Operand(this, state, insn.word(3));
 
 	Pointer<Byte> binding = state->getPointer(imageId).base;
 	Pointer<Byte> imageBase = *Pointer<Pointer<Byte>>(binding + OFFSET(vk::StorageImageDescriptor, ptr));
@@ -1007,7 +1007,7 @@
 	ASSERT(resultType.storageClass == spv::StorageClassImage);
 	ASSERT(getType(resultType.element).opcode() == spv::OpTypeInt);
 
-	auto coordinate = GenericValue(this, state, insn.word(4));
+	auto coordinate = Operand(this, state, insn.word(4));
 
 	Pointer<Byte> binding = state->getPointer(imageId).base;
 	Pointer<Byte> imageBase = *Pointer<Pointer<Byte>>(binding + OFFSET(vk::StorageImageDescriptor, ptr));
diff --git a/src/Pipeline/SpirvShaderMemory.cpp b/src/Pipeline/SpirvShaderMemory.cpp
index c656216..7d1fc93 100644
--- a/src/Pipeline/SpirvShaderMemory.cpp
+++ b/src/Pipeline/SpirvShaderMemory.cpp
@@ -236,7 +236,7 @@
 			{
 				bool interleavedByLane = IsStorageInterleavedByLane(objectTy.storageClass);
 				auto ptr = GetPointerToData(resultId, 0, state);
-				GenericValue initialValue(this, state, initializerId);
+				Operand initialValue(this, state, initializerId);
 				VisitMemoryObject(resultId, [&](const MemoryElement &el) {
 					auto p = ptr + el.offset;
 					if(interleavedByLane) { p = InterleaveByLane(p); }