[metal-writer] Emit binary operations.
This CL adds emission of binary operations to the Metal backend.
Bug: tint:8
Change-Id: I797daadd238b718b081842b63ccefab3294bc20c
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/23706
Reviewed-by: David Neto <dneto@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index 381c9f8..677a1cc 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -845,6 +845,7 @@
"src/writer/wgsl/generator_impl_array_accessor_test.cc",
"src/writer/wgsl/generator_impl_as_test.cc",
"src/writer/wgsl/generator_impl_assign_test.cc",
+ "src/writer/wgsl/generator_impl_binary_test.cc",
"src/writer/wgsl/generator_impl_break_test.cc",
"src/writer/wgsl/generator_impl_call_test.cc",
"src/writer/wgsl/generator_impl_case_test.cc",
@@ -861,7 +862,6 @@
"src/writer/wgsl/generator_impl_kill_test.cc",
"src/writer/wgsl/generator_impl_loop_test.cc",
"src/writer/wgsl/generator_impl_member_accessor_test.cc",
- "src/writer/wgsl/generator_impl_relational_test.cc",
"src/writer/wgsl/generator_impl_return_test.cc",
"src/writer/wgsl/generator_impl_switch_test.cc",
"src/writer/wgsl/generator_impl_test.cc",
@@ -886,6 +886,7 @@
source_set("tint_unittests_msl_writer_src") {
sources = [
"src/writer/msl/generator_impl_assign_test.cc",
+ "src/writer/msl/generator_impl_binary_test.cc",
"src/writer/msl/generator_impl_function_test.cc",
"src/writer/msl/generator_impl_identifier_test.cc",
"src/writer/msl/generator_impl_return_test.cc",
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 82a51a4..6659416 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -465,6 +465,7 @@
writer/wgsl/generator_impl_array_accessor_test.cc
writer/wgsl/generator_impl_as_test.cc
writer/wgsl/generator_impl_assign_test.cc
+ writer/wgsl/generator_impl_binary_test.cc
writer/wgsl/generator_impl_break_test.cc
writer/wgsl/generator_impl_call_test.cc
writer/wgsl/generator_impl_case_test.cc
@@ -481,7 +482,6 @@
writer/wgsl/generator_impl_kill_test.cc
writer/wgsl/generator_impl_loop_test.cc
writer/wgsl/generator_impl_member_accessor_test.cc
- writer/wgsl/generator_impl_relational_test.cc
writer/wgsl/generator_impl_return_test.cc
writer/wgsl/generator_impl_switch_test.cc
writer/wgsl/generator_impl_type_test.cc
@@ -494,6 +494,7 @@
if(${TINT_BUILD_MSL_WRITER})
list(APPEND TINT_TEST_SRCS
writer/msl/generator_impl_assign_test.cc
+ writer/msl/generator_impl_binary_test.cc
writer/msl/generator_impl_function_test.cc
writer/msl/generator_impl_identifier_test.cc
writer/msl/generator_impl_return_test.cc
diff --git a/src/writer/msl/generator_impl.cc b/src/writer/msl/generator_impl.cc
index ac1bc74..b399d45 100644
--- a/src/writer/msl/generator_impl.cc
+++ b/src/writer/msl/generator_impl.cc
@@ -15,6 +15,7 @@
#include "src/writer/msl/generator_impl.h"
#include "src/ast/assignment_statement.h"
+#include "src/ast/binary_expression.h"
#include "src/ast/function.h"
#include "src/ast/identifier_expression.h"
#include "src/ast/return_statement.h"
@@ -66,7 +67,91 @@
return true;
}
+bool GeneratorImpl::EmitBinary(ast::BinaryExpression* expr) {
+ out_ << "(";
+
+ if (!EmitExpression(expr->lhs())) {
+ return false;
+ }
+ out_ << " ";
+
+ switch (expr->op()) {
+ case ast::BinaryOp::kAnd:
+ out_ << "&";
+ break;
+ case ast::BinaryOp::kOr:
+ out_ << "|";
+ break;
+ case ast::BinaryOp::kXor:
+ out_ << "^";
+ break;
+ case ast::BinaryOp::kLogicalAnd:
+ out_ << "&&";
+ break;
+ case ast::BinaryOp::kLogicalOr:
+ out_ << "||";
+ break;
+ case ast::BinaryOp::kEqual:
+ out_ << "==";
+ break;
+ case ast::BinaryOp::kNotEqual:
+ out_ << "!=";
+ break;
+ case ast::BinaryOp::kLessThan:
+ out_ << "<";
+ break;
+ case ast::BinaryOp::kGreaterThan:
+ out_ << ">";
+ break;
+ case ast::BinaryOp::kLessThanEqual:
+ out_ << "<=";
+ break;
+ case ast::BinaryOp::kGreaterThanEqual:
+ out_ << ">=";
+ break;
+ case ast::BinaryOp::kShiftLeft:
+ out_ << "<<";
+ break;
+ case ast::BinaryOp::kShiftRight:
+ // TODO(dsinclair): MSL is based on C++14, and >> in C++14 has
+ // implementation-defined behaviour for negative LHS. We may have to
+ // generate extra code to implement WGSL-specified behaviour for negative
+ // LHS.
+ out_ << ">>";
+ break;
+ case ast::BinaryOp::kAdd:
+ out_ << "+";
+ break;
+ case ast::BinaryOp::kSubtract:
+ out_ << "-";
+ break;
+ case ast::BinaryOp::kMultiply:
+ out_ << "*";
+ break;
+ case ast::BinaryOp::kDivide:
+ out_ << "/";
+ break;
+ case ast::BinaryOp::kModulo:
+ out_ << "%";
+ break;
+ case ast::BinaryOp::kNone:
+ error_ = "missing binary operation type";
+ return false;
+ }
+ out_ << " ";
+
+ if (!EmitExpression(expr->rhs())) {
+ return false;
+ }
+
+ out_ << ")";
+ return true;
+}
+
bool GeneratorImpl::EmitExpression(ast::Expression* expr) {
+ if (expr->IsBinary()) {
+ return EmitBinary(expr->AsBinary());
+ }
if (expr->IsIdentifier()) {
return EmitIdentifier(expr->AsIdentifier());
}
diff --git a/src/writer/msl/generator_impl.h b/src/writer/msl/generator_impl.h
index 8617c90..5ef4407 100644
--- a/src/writer/msl/generator_impl.h
+++ b/src/writer/msl/generator_impl.h
@@ -41,6 +41,10 @@
/// @param stmt the statement to emit
/// @returns true if the statement was emitted successfully
bool EmitAssign(ast::AssignmentStatement* stmt);
+ /// Handles generating a binary expression
+ /// @param expr the binary expression
+ /// @returns true if the expression was emitted, false otherwise
+ bool EmitBinary(ast::BinaryExpression* expr);
/// Handles generate an Expression
/// @param expr the expression
/// @returns true if the expression was emitted
diff --git a/src/writer/wgsl/generator_impl_relational_test.cc b/src/writer/msl/generator_impl_binary_test.cc
similarity index 91%
copy from src/writer/wgsl/generator_impl_relational_test.cc
copy to src/writer/msl/generator_impl_binary_test.cc
index 465c149..017e6ac 100644
--- a/src/writer/wgsl/generator_impl_relational_test.cc
+++ b/src/writer/msl/generator_impl_binary_test.cc
@@ -17,11 +17,11 @@
#include "gtest/gtest.h"
#include "src/ast/binary_expression.h"
#include "src/ast/identifier_expression.h"
-#include "src/writer/wgsl/generator_impl.h"
+#include "src/writer/msl/generator_impl.h"
namespace tint {
namespace writer {
-namespace wgsl {
+namespace msl {
namespace {
struct BinaryData {
@@ -32,8 +32,8 @@
out << data.op;
return out;
}
-using BinaryTest = testing::TestWithParam<BinaryData>;
-TEST_P(BinaryTest, Emit) {
+using MslBinaryTest = testing::TestWithParam<BinaryData>;
+TEST_P(MslBinaryTest, Emit) {
auto params = GetParam();
auto left = std::make_unique<ast::IdentifierExpression>("left");
@@ -46,8 +46,8 @@
EXPECT_EQ(g.result(), params.result);
}
INSTANTIATE_TEST_SUITE_P(
- WgslGeneratorImplTest,
- BinaryTest,
+ MslGeneratorImplTest,
+ MslBinaryTest,
testing::Values(
BinaryData{"(left & right)", ast::BinaryOp::kAnd},
BinaryData{"(left | right)", ast::BinaryOp::kOr},
@@ -69,6 +69,6 @@
BinaryData{"(left % right)", ast::BinaryOp::kModulo}));
} // namespace
-} // namespace wgsl
+} // namespace msl
} // namespace writer
} // namespace tint
diff --git a/src/writer/wgsl/generator_impl_relational_test.cc b/src/writer/wgsl/generator_impl_binary_test.cc
similarity index 95%
rename from src/writer/wgsl/generator_impl_relational_test.cc
rename to src/writer/wgsl/generator_impl_binary_test.cc
index 465c149..2858f77 100644
--- a/src/writer/wgsl/generator_impl_relational_test.cc
+++ b/src/writer/wgsl/generator_impl_binary_test.cc
@@ -32,8 +32,8 @@
out << data.op;
return out;
}
-using BinaryTest = testing::TestWithParam<BinaryData>;
-TEST_P(BinaryTest, Emit) {
+using WgslBinaryTest = testing::TestWithParam<BinaryData>;
+TEST_P(WgslBinaryTest, Emit) {
auto params = GetParam();
auto left = std::make_unique<ast::IdentifierExpression>("left");
@@ -47,7 +47,7 @@
}
INSTANTIATE_TEST_SUITE_P(
WgslGeneratorImplTest,
- BinaryTest,
+ WgslBinaryTest,
testing::Values(
BinaryData{"(left & right)", ast::BinaryOp::kAnd},
BinaryData{"(left | right)", ast::BinaryOp::kOr},