GLSL: implement bitcast operators.

Bug: tint:1265
Change-Id: I6768bde2be8da7281c9516528485e49f6c7c0460
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/68380
Reviewed-by: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Stephen White <senorblanco@chromium.org>
diff --git a/src/writer/glsl/generator_impl.cc b/src/writer/glsl/generator_impl.cc
index e16b3d7..8aa6d85 100644
--- a/src/writer/glsl/generator_impl.cc
+++ b/src/writer/glsl/generator_impl.cc
@@ -177,21 +177,38 @@
 
 bool GeneratorImpl::EmitBitcast(std::ostream& out,
                                 const ast::BitcastExpression* expr) {
-  auto* type = TypeOf(expr);
-  if (auto* vec = type->UnwrapRef()->As<sem::Vector>()) {
-    type = vec->type();
-  }
+  auto* src_type = TypeOf(expr->expr);
+  auto* dst_type = TypeOf(expr);
 
-  if (!type->is_integer_scalar() && !type->is_float_scalar()) {
-    diagnostics_.add_error(diag::System::Writer,
-                           "Unable to do bitcast to type " + type->type_name());
+  if (!dst_type->is_integer_scalar_or_vector() &&
+      !dst_type->is_float_scalar_or_vector()) {
+    diagnostics_.add_error(
+        diag::System::Writer,
+        "Unable to do bitcast to type " + dst_type->type_name());
     return false;
   }
 
-  out << "as";
-  if (!EmitType(out, type, ast::StorageClass::kNone, ast::Access::kReadWrite,
-                "")) {
-    return false;
+  if (src_type == dst_type) {
+    return EmitExpression(out, expr->expr);
+  }
+
+  if (src_type->is_float_scalar_or_vector() &&
+      dst_type->is_signed_scalar_or_vector()) {
+    out << "floatBitsToInt";
+  } else if (src_type->is_float_scalar_or_vector() &&
+             dst_type->is_unsigned_scalar_or_vector()) {
+    out << "floatBitsToUint";
+  } else if (src_type->is_signed_scalar_or_vector() &&
+             dst_type->is_float_scalar_or_vector()) {
+    out << "intBitsToFloat";
+  } else if (src_type->is_unsigned_scalar_or_vector() &&
+             dst_type->is_float_scalar_or_vector()) {
+    out << "uintBitsToFloat";
+  } else {
+    if (!EmitType(out, dst_type, ast::StorageClass::kNone,
+                  ast::Access::kReadWrite, "")) {
+      return false;
+    }
   }
   out << "(";
   if (!EmitExpression(out, expr->expr)) {
diff --git a/src/writer/glsl/generator_impl_binary_test.cc b/src/writer/glsl/generator_impl_binary_test.cc
index c1b6724..b23f228 100644
--- a/src/writer/glsl/generator_impl_binary_test.cc
+++ b/src/writer/glsl/generator_impl_binary_test.cc
@@ -491,7 +491,7 @@
   tint_tmp = (tint_tmp_1);
 }
 )");
-  EXPECT_EQ(out.str(), R"(asint((tint_tmp)))");
+  EXPECT_EQ(out.str(), R"(int((tint_tmp)))");
 }
 
 TEST_F(GlslGeneratorImplTest_Binary, Call_WithLogical) {
diff --git a/src/writer/glsl/generator_impl_bitcast_test.cc b/src/writer/glsl/generator_impl_bitcast_test.cc
index d744615..140d87e 100644
--- a/src/writer/glsl/generator_impl_bitcast_test.cc
+++ b/src/writer/glsl/generator_impl_bitcast_test.cc
@@ -29,7 +29,7 @@
 
   std::stringstream out;
   ASSERT_TRUE(gen.EmitExpression(out, bitcast)) << gen.error();
-  EXPECT_EQ(out.str(), "asfloat(1)");
+  EXPECT_EQ(out.str(), "intBitsToFloat(1)");
 }
 
 TEST_F(GlslGeneratorImplTest_Bitcast, EmitExpression_Bitcast_Int) {
@@ -40,7 +40,7 @@
 
   std::stringstream out;
   ASSERT_TRUE(gen.EmitExpression(out, bitcast)) << gen.error();
-  EXPECT_EQ(out.str(), "asint(1u)");
+  EXPECT_EQ(out.str(), "int(1u)");
 }
 
 TEST_F(GlslGeneratorImplTest_Bitcast, EmitExpression_Bitcast_Uint) {
@@ -51,7 +51,7 @@
 
   std::stringstream out;
   ASSERT_TRUE(gen.EmitExpression(out, bitcast)) << gen.error();
-  EXPECT_EQ(out.str(), "asuint(1)");
+  EXPECT_EQ(out.str(), "uint(1)");
 }
 
 }  // namespace