Add support for conversion instructions

- OpSConvert, OpUConvert, OpFConvert have no valid use, as we only have
  one value width (32 bits) and these instructions perform width
  conversions only.
- OpConvertFToU, OpConvertFToS, OpConvertUToF, OpConvertSToF implemented
- OpBitcast implemented. Note that the spec looks scary wrt pointer
  types in OpBitcast, but 2.16.1 Universal Validation Rules disallows
  this use in the Logical addressing model.

Bug: b/126952020
Change-Id: I6c1c95d5ad4e19177e40ead7713bf63ffe16c679
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/26010
Tested-by: Chris Forbes <chrisforbes@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
diff --git a/src/Pipeline/SpirvShader.cpp b/src/Pipeline/SpirvShader.cpp
index 3c9afb4..6c9e66a 100644
--- a/src/Pipeline/SpirvShader.cpp
+++ b/src/Pipeline/SpirvShader.cpp
@@ -206,6 +206,12 @@
 				UNIMPLEMENTED("These instructions should have already been lowered.");
 				break;
 
+			case spv::OpFConvert:
+			case spv::OpSConvert:
+			case spv::OpUConvert:
+				UNIMPLEMENTED("No valid uses for Op*Convert until we support multiple bit widths");
+				break;
+
 			case spv::OpLoad:
 			case spv::OpAccessChain:
 			case spv::OpCompositeConstruct:
@@ -236,6 +242,11 @@
 			case spv::OpUMulExtended:
 			case spv::OpSMulExtended:
 			case spv::OpDot:
+			case spv::OpConvertFToU:
+			case spv::OpConvertFToS:
+			case spv::OpConvertSToF:
+			case spv::OpConvertUToF:
+			case spv::OpBitcast:
 				// Instructions that yield an intermediate value
 			{
 				TypeID typeId = insn.word(1);
@@ -890,6 +901,11 @@
 			case spv::OpSNegate:
 			case spv::OpFNegate:
 			case spv::OpLogicalNot:
+			case spv::OpConvertFToU:
+			case spv::OpConvertFToS:
+			case spv::OpConvertSToF:
+			case spv::OpConvertUToF:
+			case spv::OpBitcast:
 				EmitUnaryOp(insn, routine);
 				break;
 
@@ -1199,6 +1215,21 @@
 			case spv::OpFNegate:
 				dst.emplace(i, -val);
 				break;
+			case spv::OpConvertFToU:
+				dst.emplace(i, As<SIMD::Float>(SIMD::UInt(val)));
+				break;
+			case spv::OpConvertFToS:
+				dst.emplace(i, As<SIMD::Float>(SIMD::Int(val)));
+				break;
+			case spv::OpConvertSToF:
+				dst.emplace(i, SIMD::Float(As<SIMD::Int>(val)));
+				break;
+			case spv::OpConvertUToF:
+				dst.emplace(i, SIMD::Float(As<SIMD::UInt>(val)));
+				break;
+			case spv::OpBitcast:
+				dst.emplace(i, val);
+				break;
 			default:
 				UNIMPLEMENTED("Unhandled unary operator %s", OpcodeName(insn.opcode()).c_str());
 			}