[ir] Split Binary from Instruction
This CL pulls a Binary instruction out of the Instruction class and changes Instruction to just be the base class. Bug: tint:1718 Change-Id: Iab234bd8c3eeebedb56dffff7ec7244cda51d4d5 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/112320 Commit-Queue: Dan Sinclair <dsinclair@chromium.org> Reviewed-by: Ben Clayton <bclayton@google.com> Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
parent
babc21f931
commit
53f646c55c
|
@ -650,6 +650,8 @@ endif()
|
||||||
|
|
||||||
if(${TINT_BUILD_IR})
|
if(${TINT_BUILD_IR})
|
||||||
list(APPEND TINT_LIB_SRCS
|
list(APPEND TINT_LIB_SRCS
|
||||||
|
ir/binary.cc
|
||||||
|
ir/binary.h
|
||||||
ir/block.cc
|
ir/block.cc
|
||||||
ir/block.h
|
ir/block.h
|
||||||
ir/builder.cc
|
ir/builder.cc
|
||||||
|
@ -1344,9 +1346,9 @@ if(TINT_BUILD_TESTS)
|
||||||
|
|
||||||
if (${TINT_BUILD_IR})
|
if (${TINT_BUILD_IR})
|
||||||
list(APPEND TINT_TEST_SRCS
|
list(APPEND TINT_TEST_SRCS
|
||||||
|
ir/binary_test.cc
|
||||||
ir/builder_impl_test.cc
|
ir/builder_impl_test.cc
|
||||||
ir/constant_test.cc
|
ir/constant_test.cc
|
||||||
ir/instruction_test.cc
|
|
||||||
ir/temp_test.cc
|
ir/temp_test.cc
|
||||||
ir/test_helper.h
|
ir/test_helper.h
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
// Copyright 2022 The Tint Authors.
|
||||||
|
//
|
||||||
|
// 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 "src/tint/ir/binary.h"
|
||||||
|
#include "src/tint/debug.h"
|
||||||
|
|
||||||
|
TINT_INSTANTIATE_TYPEINFO(tint::ir::Binary);
|
||||||
|
|
||||||
|
namespace tint::ir {
|
||||||
|
|
||||||
|
Binary::Binary(Kind kind, const Value* result, const Value* lhs, const Value* rhs)
|
||||||
|
: kind_(kind), result_(result), lhs_(lhs), rhs_(rhs) {
|
||||||
|
TINT_ASSERT(IR, result_);
|
||||||
|
TINT_ASSERT(IR, lhs_);
|
||||||
|
TINT_ASSERT(IR, rhs_);
|
||||||
|
}
|
||||||
|
|
||||||
|
Binary::~Binary() = default;
|
||||||
|
|
||||||
|
std::ostream& Binary::ToString(std::ostream& out) const {
|
||||||
|
Result()->ToString(out) << " = ";
|
||||||
|
lhs_->ToString(out) << " ";
|
||||||
|
|
||||||
|
switch (GetKind()) {
|
||||||
|
case Binary::Kind::kAdd:
|
||||||
|
out << "+";
|
||||||
|
break;
|
||||||
|
case Binary::Kind::kSubtract:
|
||||||
|
out << "-";
|
||||||
|
break;
|
||||||
|
case Binary::Kind::kMultiply:
|
||||||
|
out << "*";
|
||||||
|
break;
|
||||||
|
case Binary::Kind::kDivide:
|
||||||
|
out << "/";
|
||||||
|
break;
|
||||||
|
case Binary::Kind::kModulo:
|
||||||
|
out << "%";
|
||||||
|
break;
|
||||||
|
case Binary::Kind::kAnd:
|
||||||
|
out << "&";
|
||||||
|
break;
|
||||||
|
case Binary::Kind::kOr:
|
||||||
|
out << "|";
|
||||||
|
break;
|
||||||
|
case Binary::Kind::kXor:
|
||||||
|
out << "^";
|
||||||
|
break;
|
||||||
|
case Binary::Kind::kLogicalAnd:
|
||||||
|
out << "&&";
|
||||||
|
break;
|
||||||
|
case Binary::Kind::kLogicalOr:
|
||||||
|
out << "||";
|
||||||
|
break;
|
||||||
|
case Binary::Kind::kEqual:
|
||||||
|
out << "==";
|
||||||
|
break;
|
||||||
|
case Binary::Kind::kNotEqual:
|
||||||
|
out << "!=";
|
||||||
|
break;
|
||||||
|
case Binary::Kind::kLessThan:
|
||||||
|
out << "<";
|
||||||
|
break;
|
||||||
|
case Binary::Kind::kGreaterThan:
|
||||||
|
out << ">";
|
||||||
|
break;
|
||||||
|
case Binary::Kind::kLessThanEqual:
|
||||||
|
out << "<=";
|
||||||
|
break;
|
||||||
|
case Binary::Kind::kGreaterThanEqual:
|
||||||
|
out << ">=";
|
||||||
|
break;
|
||||||
|
case Binary::Kind::kShiftLeft:
|
||||||
|
out << "<<";
|
||||||
|
break;
|
||||||
|
case Binary::Kind::kShiftRight:
|
||||||
|
out << ">>";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
out << " ";
|
||||||
|
rhs_->ToString(out);
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace tint::ir
|
|
@ -0,0 +1,96 @@
|
||||||
|
// Copyright 2022 The Tint Authors.
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
#ifndef SRC_TINT_IR_BINARY_H_
|
||||||
|
#define SRC_TINT_IR_BINARY_H_
|
||||||
|
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
|
#include "src/tint/castable.h"
|
||||||
|
#include "src/tint/ir/instruction.h"
|
||||||
|
#include "src/tint/ir/value.h"
|
||||||
|
|
||||||
|
namespace tint::ir {
|
||||||
|
|
||||||
|
/// An instruction in the IR.
|
||||||
|
class Binary : public Castable<Binary, Instruction> {
|
||||||
|
public:
|
||||||
|
/// The kind of instruction.
|
||||||
|
enum class Kind {
|
||||||
|
kAdd,
|
||||||
|
kSubtract,
|
||||||
|
kMultiply,
|
||||||
|
kDivide,
|
||||||
|
kModulo,
|
||||||
|
|
||||||
|
kAnd,
|
||||||
|
kOr,
|
||||||
|
kXor,
|
||||||
|
|
||||||
|
kLogicalAnd,
|
||||||
|
kLogicalOr,
|
||||||
|
|
||||||
|
kEqual,
|
||||||
|
kNotEqual,
|
||||||
|
kLessThan,
|
||||||
|
kGreaterThan,
|
||||||
|
kLessThanEqual,
|
||||||
|
kGreaterThanEqual,
|
||||||
|
|
||||||
|
kShiftLeft,
|
||||||
|
kShiftRight
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Constructor
|
||||||
|
/// @param kind the kind of binary instruction
|
||||||
|
/// @param result the result value
|
||||||
|
/// @param lhs the lhs of the instruction
|
||||||
|
/// @param rhs the rhs of the instruction
|
||||||
|
Binary(Kind kind, const Value* result, const Value* lhs, const Value* rhs);
|
||||||
|
Binary(const Binary& instr) = delete;
|
||||||
|
Binary(Binary&& instr) = delete;
|
||||||
|
~Binary() override;
|
||||||
|
|
||||||
|
Binary& operator=(const Binary& instr) = delete;
|
||||||
|
Binary& operator=(Binary&& instr) = delete;
|
||||||
|
|
||||||
|
/// @returns the kind of instruction
|
||||||
|
Kind GetKind() const { return kind_; }
|
||||||
|
|
||||||
|
/// @returns the result value for the instruction
|
||||||
|
const Value* Result() const { return result_; }
|
||||||
|
|
||||||
|
/// @returns the left-hand-side value for the instruction
|
||||||
|
const Value* LHS() const { return lhs_; }
|
||||||
|
|
||||||
|
/// @returns the right-hand-side value for the instruction
|
||||||
|
const Value* RHS() const { return rhs_; }
|
||||||
|
|
||||||
|
/// Write the instruction to the given stream
|
||||||
|
/// @param out the stream to write to
|
||||||
|
/// @returns the stream
|
||||||
|
std::ostream& ToString(std::ostream& out) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Kind kind_;
|
||||||
|
const Value* result_ = nullptr;
|
||||||
|
const Value* lhs_ = nullptr;
|
||||||
|
const Value* rhs_ = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& out, const Binary&);
|
||||||
|
|
||||||
|
} // namespace tint::ir
|
||||||
|
|
||||||
|
#endif // SRC_TINT_IR_BINARY_H_
|
|
@ -0,0 +1,499 @@
|
||||||
|
// Copyright 2022 The Tint Authors.
|
||||||
|
//
|
||||||
|
// 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 <sstream>
|
||||||
|
|
||||||
|
#include "src/tint/ir/instruction.h"
|
||||||
|
#include "src/tint/ir/test_helper.h"
|
||||||
|
|
||||||
|
namespace tint::ir {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using IR_InstructionTest = TestHelper;
|
||||||
|
|
||||||
|
TEST_F(IR_InstructionTest, CreateAnd) {
|
||||||
|
auto& b = CreateEmptyBuilder();
|
||||||
|
|
||||||
|
b.builder.next_temp_id = Temp::Id(42);
|
||||||
|
const auto* instr = b.builder.And(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
|
||||||
|
|
||||||
|
EXPECT_EQ(instr->GetKind(), Binary::Kind::kAnd);
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
||||||
|
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||||
|
auto lhs = instr->LHS()->As<Constant>();
|
||||||
|
ASSERT_TRUE(lhs->IsI32());
|
||||||
|
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||||
|
auto rhs = instr->RHS()->As<Constant>();
|
||||||
|
ASSERT_TRUE(rhs->IsI32());
|
||||||
|
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||||
|
|
||||||
|
std::stringstream str;
|
||||||
|
instr->ToString(str);
|
||||||
|
EXPECT_EQ(str.str(), "%42 = 4 & 2");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(IR_InstructionTest, CreateOr) {
|
||||||
|
auto& b = CreateEmptyBuilder();
|
||||||
|
|
||||||
|
b.builder.next_temp_id = Temp::Id(42);
|
||||||
|
const auto* instr = b.builder.Or(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
|
||||||
|
|
||||||
|
EXPECT_EQ(instr->GetKind(), Binary::Kind::kOr);
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
||||||
|
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||||
|
auto lhs = instr->LHS()->As<Constant>();
|
||||||
|
ASSERT_TRUE(lhs->IsI32());
|
||||||
|
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||||
|
auto rhs = instr->RHS()->As<Constant>();
|
||||||
|
ASSERT_TRUE(rhs->IsI32());
|
||||||
|
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||||
|
|
||||||
|
std::stringstream str;
|
||||||
|
instr->ToString(str);
|
||||||
|
EXPECT_EQ(str.str(), "%42 = 4 | 2");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(IR_InstructionTest, CreateXor) {
|
||||||
|
auto& b = CreateEmptyBuilder();
|
||||||
|
|
||||||
|
b.builder.next_temp_id = Temp::Id(42);
|
||||||
|
const auto* instr = b.builder.Xor(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
|
||||||
|
|
||||||
|
EXPECT_EQ(instr->GetKind(), Binary::Kind::kXor);
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
||||||
|
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||||
|
auto lhs = instr->LHS()->As<Constant>();
|
||||||
|
ASSERT_TRUE(lhs->IsI32());
|
||||||
|
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||||
|
auto rhs = instr->RHS()->As<Constant>();
|
||||||
|
ASSERT_TRUE(rhs->IsI32());
|
||||||
|
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||||
|
|
||||||
|
std::stringstream str;
|
||||||
|
instr->ToString(str);
|
||||||
|
EXPECT_EQ(str.str(), "%42 = 4 ^ 2");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(IR_InstructionTest, CreateLogicalAnd) {
|
||||||
|
auto& b = CreateEmptyBuilder();
|
||||||
|
|
||||||
|
b.builder.next_temp_id = Temp::Id(42);
|
||||||
|
const auto* instr =
|
||||||
|
b.builder.LogicalAnd(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
|
||||||
|
|
||||||
|
EXPECT_EQ(instr->GetKind(), Binary::Kind::kLogicalAnd);
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
||||||
|
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||||
|
auto lhs = instr->LHS()->As<Constant>();
|
||||||
|
ASSERT_TRUE(lhs->IsI32());
|
||||||
|
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||||
|
auto rhs = instr->RHS()->As<Constant>();
|
||||||
|
ASSERT_TRUE(rhs->IsI32());
|
||||||
|
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||||
|
|
||||||
|
std::stringstream str;
|
||||||
|
instr->ToString(str);
|
||||||
|
EXPECT_EQ(str.str(), "%42 = 4 && 2");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(IR_InstructionTest, CreateLogicalOr) {
|
||||||
|
auto& b = CreateEmptyBuilder();
|
||||||
|
|
||||||
|
b.builder.next_temp_id = Temp::Id(42);
|
||||||
|
const auto* instr = b.builder.LogicalOr(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
|
||||||
|
|
||||||
|
EXPECT_EQ(instr->GetKind(), Binary::Kind::kLogicalOr);
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
||||||
|
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||||
|
auto lhs = instr->LHS()->As<Constant>();
|
||||||
|
ASSERT_TRUE(lhs->IsI32());
|
||||||
|
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||||
|
auto rhs = instr->RHS()->As<Constant>();
|
||||||
|
ASSERT_TRUE(rhs->IsI32());
|
||||||
|
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||||
|
|
||||||
|
std::stringstream str;
|
||||||
|
instr->ToString(str);
|
||||||
|
EXPECT_EQ(str.str(), "%42 = 4 || 2");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(IR_InstructionTest, CreateEqual) {
|
||||||
|
auto& b = CreateEmptyBuilder();
|
||||||
|
|
||||||
|
b.builder.next_temp_id = Temp::Id(42);
|
||||||
|
const auto* instr = b.builder.Equal(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
|
||||||
|
|
||||||
|
EXPECT_EQ(instr->GetKind(), Binary::Kind::kEqual);
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
||||||
|
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||||
|
auto lhs = instr->LHS()->As<Constant>();
|
||||||
|
ASSERT_TRUE(lhs->IsI32());
|
||||||
|
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||||
|
auto rhs = instr->RHS()->As<Constant>();
|
||||||
|
ASSERT_TRUE(rhs->IsI32());
|
||||||
|
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||||
|
|
||||||
|
std::stringstream str;
|
||||||
|
instr->ToString(str);
|
||||||
|
EXPECT_EQ(str.str(), "%42 = 4 == 2");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(IR_InstructionTest, CreateNotEqual) {
|
||||||
|
auto& b = CreateEmptyBuilder();
|
||||||
|
|
||||||
|
b.builder.next_temp_id = Temp::Id(42);
|
||||||
|
const auto* instr = b.builder.NotEqual(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
|
||||||
|
|
||||||
|
EXPECT_EQ(instr->GetKind(), Binary::Kind::kNotEqual);
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
||||||
|
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||||
|
auto lhs = instr->LHS()->As<Constant>();
|
||||||
|
ASSERT_TRUE(lhs->IsI32());
|
||||||
|
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||||
|
auto rhs = instr->RHS()->As<Constant>();
|
||||||
|
ASSERT_TRUE(rhs->IsI32());
|
||||||
|
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||||
|
|
||||||
|
std::stringstream str;
|
||||||
|
instr->ToString(str);
|
||||||
|
EXPECT_EQ(str.str(), "%42 = 4 != 2");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(IR_InstructionTest, CreateLessThan) {
|
||||||
|
auto& b = CreateEmptyBuilder();
|
||||||
|
|
||||||
|
b.builder.next_temp_id = Temp::Id(42);
|
||||||
|
const auto* instr = b.builder.LessThan(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
|
||||||
|
|
||||||
|
EXPECT_EQ(instr->GetKind(), Binary::Kind::kLessThan);
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
||||||
|
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||||
|
auto lhs = instr->LHS()->As<Constant>();
|
||||||
|
ASSERT_TRUE(lhs->IsI32());
|
||||||
|
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||||
|
auto rhs = instr->RHS()->As<Constant>();
|
||||||
|
ASSERT_TRUE(rhs->IsI32());
|
||||||
|
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||||
|
|
||||||
|
std::stringstream str;
|
||||||
|
instr->ToString(str);
|
||||||
|
EXPECT_EQ(str.str(), "%42 = 4 < 2");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(IR_InstructionTest, CreateGreaterThan) {
|
||||||
|
auto& b = CreateEmptyBuilder();
|
||||||
|
|
||||||
|
b.builder.next_temp_id = Temp::Id(42);
|
||||||
|
const auto* instr =
|
||||||
|
b.builder.GreaterThan(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
|
||||||
|
|
||||||
|
EXPECT_EQ(instr->GetKind(), Binary::Kind::kGreaterThan);
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
||||||
|
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||||
|
auto lhs = instr->LHS()->As<Constant>();
|
||||||
|
ASSERT_TRUE(lhs->IsI32());
|
||||||
|
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||||
|
auto rhs = instr->RHS()->As<Constant>();
|
||||||
|
ASSERT_TRUE(rhs->IsI32());
|
||||||
|
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||||
|
|
||||||
|
std::stringstream str;
|
||||||
|
instr->ToString(str);
|
||||||
|
EXPECT_EQ(str.str(), "%42 = 4 > 2");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(IR_InstructionTest, CreateLessThanEqual) {
|
||||||
|
auto& b = CreateEmptyBuilder();
|
||||||
|
|
||||||
|
b.builder.next_temp_id = Temp::Id(42);
|
||||||
|
const auto* instr =
|
||||||
|
b.builder.LessThanEqual(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
|
||||||
|
|
||||||
|
EXPECT_EQ(instr->GetKind(), Binary::Kind::kLessThanEqual);
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
||||||
|
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||||
|
auto lhs = instr->LHS()->As<Constant>();
|
||||||
|
ASSERT_TRUE(lhs->IsI32());
|
||||||
|
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||||
|
auto rhs = instr->RHS()->As<Constant>();
|
||||||
|
ASSERT_TRUE(rhs->IsI32());
|
||||||
|
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||||
|
|
||||||
|
std::stringstream str;
|
||||||
|
instr->ToString(str);
|
||||||
|
EXPECT_EQ(str.str(), "%42 = 4 <= 2");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(IR_InstructionTest, CreateGreaterThanEqual) {
|
||||||
|
auto& b = CreateEmptyBuilder();
|
||||||
|
|
||||||
|
b.builder.next_temp_id = Temp::Id(42);
|
||||||
|
const auto* instr =
|
||||||
|
b.builder.GreaterThanEqual(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
|
||||||
|
|
||||||
|
EXPECT_EQ(instr->GetKind(), Binary::Kind::kGreaterThanEqual);
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
||||||
|
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||||
|
auto lhs = instr->LHS()->As<Constant>();
|
||||||
|
ASSERT_TRUE(lhs->IsI32());
|
||||||
|
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||||
|
auto rhs = instr->RHS()->As<Constant>();
|
||||||
|
ASSERT_TRUE(rhs->IsI32());
|
||||||
|
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||||
|
|
||||||
|
std::stringstream str;
|
||||||
|
instr->ToString(str);
|
||||||
|
EXPECT_EQ(str.str(), "%42 = 4 >= 2");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(IR_InstructionTest, CreateShiftLeft) {
|
||||||
|
auto& b = CreateEmptyBuilder();
|
||||||
|
|
||||||
|
b.builder.next_temp_id = Temp::Id(42);
|
||||||
|
const auto* instr = b.builder.ShiftLeft(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
|
||||||
|
|
||||||
|
EXPECT_EQ(instr->GetKind(), Binary::Kind::kShiftLeft);
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
||||||
|
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||||
|
auto lhs = instr->LHS()->As<Constant>();
|
||||||
|
ASSERT_TRUE(lhs->IsI32());
|
||||||
|
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||||
|
auto rhs = instr->RHS()->As<Constant>();
|
||||||
|
ASSERT_TRUE(rhs->IsI32());
|
||||||
|
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||||
|
|
||||||
|
std::stringstream str;
|
||||||
|
instr->ToString(str);
|
||||||
|
EXPECT_EQ(str.str(), "%42 = 4 << 2");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(IR_InstructionTest, CreateShiftRight) {
|
||||||
|
auto& b = CreateEmptyBuilder();
|
||||||
|
|
||||||
|
b.builder.next_temp_id = Temp::Id(42);
|
||||||
|
const auto* instr =
|
||||||
|
b.builder.ShiftRight(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
|
||||||
|
|
||||||
|
EXPECT_EQ(instr->GetKind(), Binary::Kind::kShiftRight);
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
||||||
|
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||||
|
auto lhs = instr->LHS()->As<Constant>();
|
||||||
|
ASSERT_TRUE(lhs->IsI32());
|
||||||
|
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||||
|
auto rhs = instr->RHS()->As<Constant>();
|
||||||
|
ASSERT_TRUE(rhs->IsI32());
|
||||||
|
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||||
|
|
||||||
|
std::stringstream str;
|
||||||
|
instr->ToString(str);
|
||||||
|
EXPECT_EQ(str.str(), "%42 = 4 >> 2");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(IR_InstructionTest, CreateAdd) {
|
||||||
|
auto& b = CreateEmptyBuilder();
|
||||||
|
|
||||||
|
b.builder.next_temp_id = Temp::Id(42);
|
||||||
|
const auto* instr = b.builder.Add(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
|
||||||
|
|
||||||
|
EXPECT_EQ(instr->GetKind(), Binary::Kind::kAdd);
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
||||||
|
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||||
|
auto lhs = instr->LHS()->As<Constant>();
|
||||||
|
ASSERT_TRUE(lhs->IsI32());
|
||||||
|
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||||
|
auto rhs = instr->RHS()->As<Constant>();
|
||||||
|
ASSERT_TRUE(rhs->IsI32());
|
||||||
|
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||||
|
|
||||||
|
std::stringstream str;
|
||||||
|
instr->ToString(str);
|
||||||
|
EXPECT_EQ(str.str(), "%42 = 4 + 2");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(IR_InstructionTest, CreateSubtract) {
|
||||||
|
auto& b = CreateEmptyBuilder();
|
||||||
|
|
||||||
|
b.builder.next_temp_id = Temp::Id(42);
|
||||||
|
const auto* instr = b.builder.Subtract(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
|
||||||
|
|
||||||
|
EXPECT_EQ(instr->GetKind(), Binary::Kind::kSubtract);
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
||||||
|
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||||
|
auto lhs = instr->LHS()->As<Constant>();
|
||||||
|
ASSERT_TRUE(lhs->IsI32());
|
||||||
|
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||||
|
auto rhs = instr->RHS()->As<Constant>();
|
||||||
|
ASSERT_TRUE(rhs->IsI32());
|
||||||
|
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||||
|
|
||||||
|
std::stringstream str;
|
||||||
|
instr->ToString(str);
|
||||||
|
EXPECT_EQ(str.str(), "%42 = 4 - 2");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(IR_InstructionTest, CreateMultiply) {
|
||||||
|
auto& b = CreateEmptyBuilder();
|
||||||
|
|
||||||
|
b.builder.next_temp_id = Temp::Id(42);
|
||||||
|
const auto* instr = b.builder.Multiply(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
|
||||||
|
|
||||||
|
EXPECT_EQ(instr->GetKind(), Binary::Kind::kMultiply);
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
||||||
|
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||||
|
auto lhs = instr->LHS()->As<Constant>();
|
||||||
|
ASSERT_TRUE(lhs->IsI32());
|
||||||
|
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||||
|
auto rhs = instr->RHS()->As<Constant>();
|
||||||
|
ASSERT_TRUE(rhs->IsI32());
|
||||||
|
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||||
|
|
||||||
|
std::stringstream str;
|
||||||
|
instr->ToString(str);
|
||||||
|
EXPECT_EQ(str.str(), "%42 = 4 * 2");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(IR_InstructionTest, CreateDivide) {
|
||||||
|
auto& b = CreateEmptyBuilder();
|
||||||
|
|
||||||
|
b.builder.next_temp_id = Temp::Id(42);
|
||||||
|
const auto* instr = b.builder.Divide(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
|
||||||
|
|
||||||
|
EXPECT_EQ(instr->GetKind(), Binary::Kind::kDivide);
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
||||||
|
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||||
|
auto lhs = instr->LHS()->As<Constant>();
|
||||||
|
ASSERT_TRUE(lhs->IsI32());
|
||||||
|
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||||
|
auto rhs = instr->RHS()->As<Constant>();
|
||||||
|
ASSERT_TRUE(rhs->IsI32());
|
||||||
|
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||||
|
|
||||||
|
std::stringstream str;
|
||||||
|
instr->ToString(str);
|
||||||
|
EXPECT_EQ(str.str(), "%42 = 4 / 2");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(IR_InstructionTest, CreateModulo) {
|
||||||
|
auto& b = CreateEmptyBuilder();
|
||||||
|
|
||||||
|
b.builder.next_temp_id = Temp::Id(42);
|
||||||
|
const auto* instr = b.builder.Modulo(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
|
||||||
|
|
||||||
|
EXPECT_EQ(instr->GetKind(), Binary::Kind::kModulo);
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
||||||
|
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||||
|
auto lhs = instr->LHS()->As<Constant>();
|
||||||
|
ASSERT_TRUE(lhs->IsI32());
|
||||||
|
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||||
|
|
||||||
|
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||||
|
auto rhs = instr->RHS()->As<Constant>();
|
||||||
|
ASSERT_TRUE(rhs->IsI32());
|
||||||
|
EXPECT_EQ(i32(2), rhs->AsI32());
|
||||||
|
|
||||||
|
std::stringstream str;
|
||||||
|
instr->ToString(str);
|
||||||
|
EXPECT_EQ(str.str(), "%42 = 4 % 2");
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
} // namespace tint::ir
|
|
@ -97,82 +97,80 @@ Temp::Id Builder::AllocateTempId() {
|
||||||
return next_temp_id++;
|
return next_temp_id++;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Instruction* Builder::CreateInstruction(Instruction::Kind kind,
|
const Binary* Builder::CreateBinary(Binary::Kind kind, const Value* lhs, const Value* rhs) {
|
||||||
const Value* lhs,
|
return ir.instructions.Create<ir::Binary>(kind, Temp(), lhs, rhs);
|
||||||
const Value* rhs) {
|
|
||||||
return ir.instructions.Create<ir::Instruction>(kind, Temp(), lhs, rhs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const Instruction* Builder::And(const Value* lhs, const Value* rhs) {
|
const Binary* Builder::And(const Value* lhs, const Value* rhs) {
|
||||||
return CreateInstruction(Instruction::Kind::kAnd, lhs, rhs);
|
return CreateBinary(Binary::Kind::kAnd, lhs, rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Instruction* Builder::Or(const Value* lhs, const Value* rhs) {
|
const Binary* Builder::Or(const Value* lhs, const Value* rhs) {
|
||||||
return CreateInstruction(Instruction::Kind::kOr, lhs, rhs);
|
return CreateBinary(Binary::Kind::kOr, lhs, rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Instruction* Builder::Xor(const Value* lhs, const Value* rhs) {
|
const Binary* Builder::Xor(const Value* lhs, const Value* rhs) {
|
||||||
return CreateInstruction(Instruction::Kind::kXor, lhs, rhs);
|
return CreateBinary(Binary::Kind::kXor, lhs, rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Instruction* Builder::LogicalAnd(const Value* lhs, const Value* rhs) {
|
const Binary* Builder::LogicalAnd(const Value* lhs, const Value* rhs) {
|
||||||
return CreateInstruction(Instruction::Kind::kLogicalAnd, lhs, rhs);
|
return CreateBinary(Binary::Kind::kLogicalAnd, lhs, rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Instruction* Builder::LogicalOr(const Value* lhs, const Value* rhs) {
|
const Binary* Builder::LogicalOr(const Value* lhs, const Value* rhs) {
|
||||||
return CreateInstruction(Instruction::Kind::kLogicalOr, lhs, rhs);
|
return CreateBinary(Binary::Kind::kLogicalOr, lhs, rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Instruction* Builder::Equal(const Value* lhs, const Value* rhs) {
|
const Binary* Builder::Equal(const Value* lhs, const Value* rhs) {
|
||||||
return CreateInstruction(Instruction::Kind::kEqual, lhs, rhs);
|
return CreateBinary(Binary::Kind::kEqual, lhs, rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Instruction* Builder::NotEqual(const Value* lhs, const Value* rhs) {
|
const Binary* Builder::NotEqual(const Value* lhs, const Value* rhs) {
|
||||||
return CreateInstruction(Instruction::Kind::kNotEqual, lhs, rhs);
|
return CreateBinary(Binary::Kind::kNotEqual, lhs, rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Instruction* Builder::LessThan(const Value* lhs, const Value* rhs) {
|
const Binary* Builder::LessThan(const Value* lhs, const Value* rhs) {
|
||||||
return CreateInstruction(Instruction::Kind::kLessThan, lhs, rhs);
|
return CreateBinary(Binary::Kind::kLessThan, lhs, rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Instruction* Builder::GreaterThan(const Value* lhs, const Value* rhs) {
|
const Binary* Builder::GreaterThan(const Value* lhs, const Value* rhs) {
|
||||||
return CreateInstruction(Instruction::Kind::kGreaterThan, lhs, rhs);
|
return CreateBinary(Binary::Kind::kGreaterThan, lhs, rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Instruction* Builder::LessThanEqual(const Value* lhs, const Value* rhs) {
|
const Binary* Builder::LessThanEqual(const Value* lhs, const Value* rhs) {
|
||||||
return CreateInstruction(Instruction::Kind::kLessThanEqual, lhs, rhs);
|
return CreateBinary(Binary::Kind::kLessThanEqual, lhs, rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Instruction* Builder::GreaterThanEqual(const Value* lhs, const Value* rhs) {
|
const Binary* Builder::GreaterThanEqual(const Value* lhs, const Value* rhs) {
|
||||||
return CreateInstruction(Instruction::Kind::kGreaterThanEqual, lhs, rhs);
|
return CreateBinary(Binary::Kind::kGreaterThanEqual, lhs, rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Instruction* Builder::ShiftLeft(const Value* lhs, const Value* rhs) {
|
const Binary* Builder::ShiftLeft(const Value* lhs, const Value* rhs) {
|
||||||
return CreateInstruction(Instruction::Kind::kShiftLeft, lhs, rhs);
|
return CreateBinary(Binary::Kind::kShiftLeft, lhs, rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Instruction* Builder::ShiftRight(const Value* lhs, const Value* rhs) {
|
const Binary* Builder::ShiftRight(const Value* lhs, const Value* rhs) {
|
||||||
return CreateInstruction(Instruction::Kind::kShiftRight, lhs, rhs);
|
return CreateBinary(Binary::Kind::kShiftRight, lhs, rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Instruction* Builder::Add(const Value* lhs, const Value* rhs) {
|
const Binary* Builder::Add(const Value* lhs, const Value* rhs) {
|
||||||
return CreateInstruction(Instruction::Kind::kAdd, lhs, rhs);
|
return CreateBinary(Binary::Kind::kAdd, lhs, rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Instruction* Builder::Subtract(const Value* lhs, const Value* rhs) {
|
const Binary* Builder::Subtract(const Value* lhs, const Value* rhs) {
|
||||||
return CreateInstruction(Instruction::Kind::kSubtract, lhs, rhs);
|
return CreateBinary(Binary::Kind::kSubtract, lhs, rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Instruction* Builder::Multiply(const Value* lhs, const Value* rhs) {
|
const Binary* Builder::Multiply(const Value* lhs, const Value* rhs) {
|
||||||
return CreateInstruction(Instruction::Kind::kMultiply, lhs, rhs);
|
return CreateBinary(Binary::Kind::kMultiply, lhs, rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Instruction* Builder::Divide(const Value* lhs, const Value* rhs) {
|
const Binary* Builder::Divide(const Value* lhs, const Value* rhs) {
|
||||||
return CreateInstruction(Instruction::Kind::kDivide, lhs, rhs);
|
return CreateBinary(Binary::Kind::kDivide, lhs, rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Instruction* Builder::Modulo(const Value* lhs, const Value* rhs) {
|
const Binary* Builder::Modulo(const Value* lhs, const Value* rhs) {
|
||||||
return CreateInstruction(Instruction::Kind::kModulo, lhs, rhs);
|
return CreateBinary(Binary::Kind::kModulo, lhs, rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace tint::ir
|
} // namespace tint::ir
|
||||||
|
|
|
@ -15,10 +15,10 @@
|
||||||
#ifndef SRC_TINT_IR_BUILDER_H_
|
#ifndef SRC_TINT_IR_BUILDER_H_
|
||||||
#define SRC_TINT_IR_BUILDER_H_
|
#define SRC_TINT_IR_BUILDER_H_
|
||||||
|
|
||||||
|
#include "src/tint/ir/binary.h"
|
||||||
#include "src/tint/ir/constant.h"
|
#include "src/tint/ir/constant.h"
|
||||||
#include "src/tint/ir/function.h"
|
#include "src/tint/ir/function.h"
|
||||||
#include "src/tint/ir/if.h"
|
#include "src/tint/ir/if.h"
|
||||||
#include "src/tint/ir/instruction.h"
|
|
||||||
#include "src/tint/ir/loop.h"
|
#include "src/tint/ir/loop.h"
|
||||||
#include "src/tint/ir/module.h"
|
#include "src/tint/ir/module.h"
|
||||||
#include "src/tint/ir/switch.h"
|
#include "src/tint/ir/switch.h"
|
||||||
|
@ -102,117 +102,115 @@ class Builder {
|
||||||
/// @param lhs the left-hand-side of the operation
|
/// @param lhs the left-hand-side of the operation
|
||||||
/// @param rhs the right-hand-side of the operation
|
/// @param rhs the right-hand-side of the operation
|
||||||
/// @returns the operation
|
/// @returns the operation
|
||||||
const Instruction* CreateInstruction(Instruction::Kind kind,
|
const Binary* CreateBinary(Binary::Kind kind, const Value* lhs, const Value* rhs);
|
||||||
const Value* lhs,
|
|
||||||
const Value* rhs);
|
|
||||||
|
|
||||||
/// Creates an And operation
|
/// Creates an And operation
|
||||||
/// @param lhs the lhs of the add
|
/// @param lhs the lhs of the add
|
||||||
/// @param rhs the rhs of the add
|
/// @param rhs the rhs of the add
|
||||||
/// @returns the operation
|
/// @returns the operation
|
||||||
const Instruction* And(const Value* lhs, const Value* rhs);
|
const Binary* And(const Value* lhs, const Value* rhs);
|
||||||
|
|
||||||
/// Creates an Or operation
|
/// Creates an Or operation
|
||||||
/// @param lhs the lhs of the add
|
/// @param lhs the lhs of the add
|
||||||
/// @param rhs the rhs of the add
|
/// @param rhs the rhs of the add
|
||||||
/// @returns the operation
|
/// @returns the operation
|
||||||
const Instruction* Or(const Value* lhs, const Value* rhs);
|
const Binary* Or(const Value* lhs, const Value* rhs);
|
||||||
|
|
||||||
/// Creates an Xor operation
|
/// Creates an Xor operation
|
||||||
/// @param lhs the lhs of the add
|
/// @param lhs the lhs of the add
|
||||||
/// @param rhs the rhs of the add
|
/// @param rhs the rhs of the add
|
||||||
/// @returns the operation
|
/// @returns the operation
|
||||||
const Instruction* Xor(const Value* lhs, const Value* rhs);
|
const Binary* Xor(const Value* lhs, const Value* rhs);
|
||||||
|
|
||||||
/// Creates an LogicalAnd operation
|
/// Creates an LogicalAnd operation
|
||||||
/// @param lhs the lhs of the add
|
/// @param lhs the lhs of the add
|
||||||
/// @param rhs the rhs of the add
|
/// @param rhs the rhs of the add
|
||||||
/// @returns the operation
|
/// @returns the operation
|
||||||
const Instruction* LogicalAnd(const Value* lhs, const Value* rhs);
|
const Binary* LogicalAnd(const Value* lhs, const Value* rhs);
|
||||||
|
|
||||||
/// Creates an LogicalOr operation
|
/// Creates an LogicalOr operation
|
||||||
/// @param lhs the lhs of the add
|
/// @param lhs the lhs of the add
|
||||||
/// @param rhs the rhs of the add
|
/// @param rhs the rhs of the add
|
||||||
/// @returns the operation
|
/// @returns the operation
|
||||||
const Instruction* LogicalOr(const Value* lhs, const Value* rhs);
|
const Binary* LogicalOr(const Value* lhs, const Value* rhs);
|
||||||
|
|
||||||
/// Creates an Equal operation
|
/// Creates an Equal operation
|
||||||
/// @param lhs the lhs of the add
|
/// @param lhs the lhs of the add
|
||||||
/// @param rhs the rhs of the add
|
/// @param rhs the rhs of the add
|
||||||
/// @returns the operation
|
/// @returns the operation
|
||||||
const Instruction* Equal(const Value* lhs, const Value* rhs);
|
const Binary* Equal(const Value* lhs, const Value* rhs);
|
||||||
|
|
||||||
/// Creates an NotEqual operation
|
/// Creates an NotEqual operation
|
||||||
/// @param lhs the lhs of the add
|
/// @param lhs the lhs of the add
|
||||||
/// @param rhs the rhs of the add
|
/// @param rhs the rhs of the add
|
||||||
/// @returns the operation
|
/// @returns the operation
|
||||||
const Instruction* NotEqual(const Value* lhs, const Value* rhs);
|
const Binary* NotEqual(const Value* lhs, const Value* rhs);
|
||||||
|
|
||||||
/// Creates an LessThan operation
|
/// Creates an LessThan operation
|
||||||
/// @param lhs the lhs of the add
|
/// @param lhs the lhs of the add
|
||||||
/// @param rhs the rhs of the add
|
/// @param rhs the rhs of the add
|
||||||
/// @returns the operation
|
/// @returns the operation
|
||||||
const Instruction* LessThan(const Value* lhs, const Value* rhs);
|
const Binary* LessThan(const Value* lhs, const Value* rhs);
|
||||||
|
|
||||||
/// Creates an GreaterThan operation
|
/// Creates an GreaterThan operation
|
||||||
/// @param lhs the lhs of the add
|
/// @param lhs the lhs of the add
|
||||||
/// @param rhs the rhs of the add
|
/// @param rhs the rhs of the add
|
||||||
/// @returns the operation
|
/// @returns the operation
|
||||||
const Instruction* GreaterThan(const Value* lhs, const Value* rhs);
|
const Binary* GreaterThan(const Value* lhs, const Value* rhs);
|
||||||
|
|
||||||
/// Creates an LessThanEqual operation
|
/// Creates an LessThanEqual operation
|
||||||
/// @param lhs the lhs of the add
|
/// @param lhs the lhs of the add
|
||||||
/// @param rhs the rhs of the add
|
/// @param rhs the rhs of the add
|
||||||
/// @returns the operation
|
/// @returns the operation
|
||||||
const Instruction* LessThanEqual(const Value* lhs, const Value* rhs);
|
const Binary* LessThanEqual(const Value* lhs, const Value* rhs);
|
||||||
|
|
||||||
/// Creates an GreaterThanEqual operation
|
/// Creates an GreaterThanEqual operation
|
||||||
/// @param lhs the lhs of the add
|
/// @param lhs the lhs of the add
|
||||||
/// @param rhs the rhs of the add
|
/// @param rhs the rhs of the add
|
||||||
/// @returns the operation
|
/// @returns the operation
|
||||||
const Instruction* GreaterThanEqual(const Value* lhs, const Value* rhs);
|
const Binary* GreaterThanEqual(const Value* lhs, const Value* rhs);
|
||||||
|
|
||||||
/// Creates an ShiftLeft operation
|
/// Creates an ShiftLeft operation
|
||||||
/// @param lhs the lhs of the add
|
/// @param lhs the lhs of the add
|
||||||
/// @param rhs the rhs of the add
|
/// @param rhs the rhs of the add
|
||||||
/// @returns the operation
|
/// @returns the operation
|
||||||
const Instruction* ShiftLeft(const Value* lhs, const Value* rhs);
|
const Binary* ShiftLeft(const Value* lhs, const Value* rhs);
|
||||||
|
|
||||||
/// Creates an ShiftRight operation
|
/// Creates an ShiftRight operation
|
||||||
/// @param lhs the lhs of the add
|
/// @param lhs the lhs of the add
|
||||||
/// @param rhs the rhs of the add
|
/// @param rhs the rhs of the add
|
||||||
/// @returns the operation
|
/// @returns the operation
|
||||||
const Instruction* ShiftRight(const Value* lhs, const Value* rhs);
|
const Binary* ShiftRight(const Value* lhs, const Value* rhs);
|
||||||
|
|
||||||
/// Creates an Add operation
|
/// Creates an Add operation
|
||||||
/// @param lhs the lhs of the add
|
/// @param lhs the lhs of the add
|
||||||
/// @param rhs the rhs of the add
|
/// @param rhs the rhs of the add
|
||||||
/// @returns the operation
|
/// @returns the operation
|
||||||
const Instruction* Add(const Value* lhs, const Value* rhs);
|
const Binary* Add(const Value* lhs, const Value* rhs);
|
||||||
|
|
||||||
/// Creates an Subtract operation
|
/// Creates an Subtract operation
|
||||||
/// @param lhs the lhs of the add
|
/// @param lhs the lhs of the add
|
||||||
/// @param rhs the rhs of the add
|
/// @param rhs the rhs of the add
|
||||||
/// @returns the operation
|
/// @returns the operation
|
||||||
const Instruction* Subtract(const Value* lhs, const Value* rhs);
|
const Binary* Subtract(const Value* lhs, const Value* rhs);
|
||||||
|
|
||||||
/// Creates an Multiply operation
|
/// Creates an Multiply operation
|
||||||
/// @param lhs the lhs of the add
|
/// @param lhs the lhs of the add
|
||||||
/// @param rhs the rhs of the add
|
/// @param rhs the rhs of the add
|
||||||
/// @returns the operation
|
/// @returns the operation
|
||||||
const Instruction* Multiply(const Value* lhs, const Value* rhs);
|
const Binary* Multiply(const Value* lhs, const Value* rhs);
|
||||||
|
|
||||||
/// Creates an Divide operation
|
/// Creates an Divide operation
|
||||||
/// @param lhs the lhs of the add
|
/// @param lhs the lhs of the add
|
||||||
/// @param rhs the rhs of the add
|
/// @param rhs the rhs of the add
|
||||||
/// @returns the operation
|
/// @returns the operation
|
||||||
const Instruction* Divide(const Value* lhs, const Value* rhs);
|
const Binary* Divide(const Value* lhs, const Value* rhs);
|
||||||
|
|
||||||
/// Creates an Modulo operation
|
/// Creates an Modulo operation
|
||||||
/// @param lhs the lhs of the add
|
/// @param lhs the lhs of the add
|
||||||
/// @param rhs the rhs of the add
|
/// @param rhs the rhs of the add
|
||||||
/// @returns the operation
|
/// @returns the operation
|
||||||
const Instruction* Modulo(const Value* lhs, const Value* rhs);
|
const Binary* Modulo(const Value* lhs, const Value* rhs);
|
||||||
|
|
||||||
/// @returns a unique temp id
|
/// @returns a unique temp id
|
||||||
Temp::Id AllocateTempId();
|
Temp::Id AllocateTempId();
|
||||||
|
|
|
@ -562,7 +562,7 @@ utils::Result<const Value*> BuilderImpl::EmitBinary(const ast::BinaryExpression*
|
||||||
return utils::Failure;
|
return utils::Failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Instruction* instr = nullptr;
|
const Binary* instr = nullptr;
|
||||||
switch (expr->op) {
|
switch (expr->op) {
|
||||||
case ast::BinaryOp::kAnd:
|
case ast::BinaryOp::kAnd:
|
||||||
instr = builder.And(lhs.Get(), rhs.Get());
|
instr = builder.And(lhs.Get(), rhs.Get());
|
||||||
|
|
|
@ -18,91 +18,8 @@ TINT_INSTANTIATE_TYPEINFO(tint::ir::Instruction);
|
||||||
|
|
||||||
namespace tint::ir {
|
namespace tint::ir {
|
||||||
|
|
||||||
Instruction::Instruction() {}
|
Instruction::Instruction() = default;
|
||||||
|
|
||||||
Instruction::Instruction(Kind kind, const Value* result, const Value* lhs, const Value* rhs)
|
|
||||||
: kind_(kind), result_(result), args_({lhs, rhs}) {}
|
|
||||||
|
|
||||||
Instruction::Instruction(const Instruction&) = default;
|
|
||||||
|
|
||||||
Instruction::Instruction(Instruction&& instr) = default;
|
|
||||||
|
|
||||||
Instruction::~Instruction() = default;
|
Instruction::~Instruction() = default;
|
||||||
|
|
||||||
Instruction& Instruction::operator=(const Instruction& instr) = default;
|
|
||||||
|
|
||||||
Instruction& Instruction::operator=(Instruction&& instr) = default;
|
|
||||||
|
|
||||||
std::ostream& Instruction::ToString(std::ostream& out) const {
|
|
||||||
Result()->ToString(out) << " = ";
|
|
||||||
if (HasLHS()) {
|
|
||||||
LHS()->ToString(out);
|
|
||||||
}
|
|
||||||
out << " ";
|
|
||||||
|
|
||||||
switch (GetKind()) {
|
|
||||||
case Instruction::Kind::kAdd:
|
|
||||||
out << "+";
|
|
||||||
break;
|
|
||||||
case Instruction::Kind::kSubtract:
|
|
||||||
out << "-";
|
|
||||||
break;
|
|
||||||
case Instruction::Kind::kMultiply:
|
|
||||||
out << "*";
|
|
||||||
break;
|
|
||||||
case Instruction::Kind::kDivide:
|
|
||||||
out << "/";
|
|
||||||
break;
|
|
||||||
case Instruction::Kind::kModulo:
|
|
||||||
out << "%";
|
|
||||||
break;
|
|
||||||
case Instruction::Kind::kAnd:
|
|
||||||
out << "&";
|
|
||||||
break;
|
|
||||||
case Instruction::Kind::kOr:
|
|
||||||
out << "|";
|
|
||||||
break;
|
|
||||||
case Instruction::Kind::kXor:
|
|
||||||
out << "^";
|
|
||||||
break;
|
|
||||||
case Instruction::Kind::kLogicalAnd:
|
|
||||||
out << "&&";
|
|
||||||
break;
|
|
||||||
case Instruction::Kind::kLogicalOr:
|
|
||||||
out << "||";
|
|
||||||
break;
|
|
||||||
case Instruction::Kind::kEqual:
|
|
||||||
out << "==";
|
|
||||||
break;
|
|
||||||
case Instruction::Kind::kNotEqual:
|
|
||||||
out << "!=";
|
|
||||||
break;
|
|
||||||
case Instruction::Kind::kLessThan:
|
|
||||||
out << "<";
|
|
||||||
break;
|
|
||||||
case Instruction::Kind::kGreaterThan:
|
|
||||||
out << ">";
|
|
||||||
break;
|
|
||||||
case Instruction::Kind::kLessThanEqual:
|
|
||||||
out << "<=";
|
|
||||||
break;
|
|
||||||
case Instruction::Kind::kGreaterThanEqual:
|
|
||||||
out << ">=";
|
|
||||||
break;
|
|
||||||
case Instruction::Kind::kShiftLeft:
|
|
||||||
out << "<<";
|
|
||||||
break;
|
|
||||||
case Instruction::Kind::kShiftRight:
|
|
||||||
out << ">>";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (HasRHS()) {
|
|
||||||
out << " ";
|
|
||||||
RHS()->ToString(out);
|
|
||||||
}
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace tint::ir
|
} // namespace tint::ir
|
||||||
|
|
|
@ -18,99 +18,28 @@
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
|
||||||
#include "src/tint/castable.h"
|
#include "src/tint/castable.h"
|
||||||
#include "src/tint/debug.h"
|
|
||||||
#include "src/tint/ir/value.h"
|
|
||||||
#include "src/tint/utils/vector.h"
|
|
||||||
|
|
||||||
namespace tint::ir {
|
namespace tint::ir {
|
||||||
|
|
||||||
/// An instruction in the IR.
|
/// An instruction in the IR.
|
||||||
class Instruction : public Castable<Instruction> {
|
class Instruction : public Castable<Instruction> {
|
||||||
public:
|
public:
|
||||||
/// The kind of instruction.
|
Instruction(const Instruction& instr) = delete;
|
||||||
enum class Kind {
|
Instruction(Instruction&& instr) = delete;
|
||||||
kAdd,
|
|
||||||
kSubtract,
|
|
||||||
kMultiply,
|
|
||||||
kDivide,
|
|
||||||
kModulo,
|
|
||||||
|
|
||||||
kAnd,
|
|
||||||
kOr,
|
|
||||||
kXor,
|
|
||||||
|
|
||||||
kLogicalAnd,
|
|
||||||
kLogicalOr,
|
|
||||||
|
|
||||||
kEqual,
|
|
||||||
kNotEqual,
|
|
||||||
kLessThan,
|
|
||||||
kGreaterThan,
|
|
||||||
kLessThanEqual,
|
|
||||||
kGreaterThanEqual,
|
|
||||||
|
|
||||||
kShiftLeft,
|
|
||||||
kShiftRight
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Constructor
|
|
||||||
Instruction();
|
|
||||||
/// Constructor
|
|
||||||
/// @param kind the kind of instruction
|
|
||||||
/// @param result the result value
|
|
||||||
/// @param lhs the lhs of the instruction
|
|
||||||
/// @param rhs the rhs of the instruction
|
|
||||||
Instruction(Kind kind, const Value* result, const Value* lhs, const Value* rhs);
|
|
||||||
/// Copy constructor
|
|
||||||
/// @param instr the instruction to copy from
|
|
||||||
Instruction(const Instruction& instr);
|
|
||||||
/// Move constructor
|
|
||||||
/// @param instr the instruction to move from
|
|
||||||
Instruction(Instruction&& instr);
|
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~Instruction() override;
|
~Instruction() override;
|
||||||
|
|
||||||
/// Copy assign
|
Instruction& operator=(const Instruction& instr) = delete;
|
||||||
/// @param instr the instruction to copy from
|
Instruction& operator=(Instruction&& instr) = delete;
|
||||||
/// @returns a reference to this
|
|
||||||
Instruction& operator=(const Instruction& instr);
|
|
||||||
/// Move assign
|
|
||||||
/// @param instr the instruction to move from
|
|
||||||
/// @returns a reference to this
|
|
||||||
Instruction& operator=(Instruction&& instr);
|
|
||||||
|
|
||||||
/// @returns the kind of instruction
|
/// Write the instruction to the given stream
|
||||||
Kind GetKind() const { return kind_; }
|
|
||||||
|
|
||||||
/// @returns the result value for the instruction
|
|
||||||
const Value* Result() const { return result_; }
|
|
||||||
|
|
||||||
/// @returns true if the instruction has a LHS
|
|
||||||
bool HasLHS() const { return args_.Length() >= 1; }
|
|
||||||
/// @returns the left-hand-side value for the instruction
|
|
||||||
const Value* LHS() const {
|
|
||||||
TINT_ASSERT(IR, HasLHS());
|
|
||||||
return args_[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @returns true if the instruction has a RHS
|
|
||||||
bool HasRHS() const { return args_.Length() >= 2; }
|
|
||||||
/// @returns the right-hand-side value for the instruction
|
|
||||||
const Value* RHS() const {
|
|
||||||
TINT_ASSERT(IR, HasRHS());
|
|
||||||
return args_[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Write the instructino to the given stream
|
|
||||||
/// @param out the stream to write to
|
/// @param out the stream to write to
|
||||||
/// @returns the stream
|
/// @returns the stream
|
||||||
std::ostream& ToString(std::ostream& out) const;
|
virtual std::ostream& ToString(std::ostream& out) const = 0;
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
Kind kind_;
|
/// Constructor
|
||||||
|
Instruction();
|
||||||
const Value* result_;
|
|
||||||
utils::Vector<const Value*, 2> args_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace tint::ir
|
} // namespace tint::ir
|
||||||
|
|
|
@ -20,9 +20,9 @@
|
||||||
namespace tint::ir {
|
namespace tint::ir {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using IR_InstructionTest = TestHelper;
|
using IR_BinaryTest = TestHelper;
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, CreateAnd) {
|
TEST_F(IR_BinaryTest, CreateAnd) {
|
||||||
auto& b = CreateEmptyBuilder();
|
auto& b = CreateEmptyBuilder();
|
||||||
|
|
||||||
b.builder.next_temp_id = Temp::Id(42);
|
b.builder.next_temp_id = Temp::Id(42);
|
||||||
|
@ -33,13 +33,11 @@ TEST_F(IR_InstructionTest, CreateAnd) {
|
||||||
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
||||||
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||||
|
|
||||||
ASSERT_TRUE(instr->HasLHS());
|
|
||||||
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||||
auto lhs = instr->LHS()->As<Constant>();
|
auto lhs = instr->LHS()->As<Constant>();
|
||||||
ASSERT_TRUE(lhs->IsI32());
|
ASSERT_TRUE(lhs->IsI32());
|
||||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||||
|
|
||||||
ASSERT_TRUE(instr->HasRHS());
|
|
||||||
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||||
auto rhs = instr->RHS()->As<Constant>();
|
auto rhs = instr->RHS()->As<Constant>();
|
||||||
ASSERT_TRUE(rhs->IsI32());
|
ASSERT_TRUE(rhs->IsI32());
|
||||||
|
@ -50,7 +48,7 @@ TEST_F(IR_InstructionTest, CreateAnd) {
|
||||||
EXPECT_EQ(str.str(), "%42 = 4 & 2");
|
EXPECT_EQ(str.str(), "%42 = 4 & 2");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, CreateOr) {
|
TEST_F(IR_BinaryTest, CreateOr) {
|
||||||
auto& b = CreateEmptyBuilder();
|
auto& b = CreateEmptyBuilder();
|
||||||
|
|
||||||
b.builder.next_temp_id = Temp::Id(42);
|
b.builder.next_temp_id = Temp::Id(42);
|
||||||
|
@ -61,13 +59,11 @@ TEST_F(IR_InstructionTest, CreateOr) {
|
||||||
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
||||||
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||||
|
|
||||||
ASSERT_TRUE(instr->HasLHS());
|
|
||||||
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||||
auto lhs = instr->LHS()->As<Constant>();
|
auto lhs = instr->LHS()->As<Constant>();
|
||||||
ASSERT_TRUE(lhs->IsI32());
|
ASSERT_TRUE(lhs->IsI32());
|
||||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||||
|
|
||||||
ASSERT_TRUE(instr->HasRHS());
|
|
||||||
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||||
auto rhs = instr->RHS()->As<Constant>();
|
auto rhs = instr->RHS()->As<Constant>();
|
||||||
ASSERT_TRUE(rhs->IsI32());
|
ASSERT_TRUE(rhs->IsI32());
|
||||||
|
@ -78,7 +74,7 @@ TEST_F(IR_InstructionTest, CreateOr) {
|
||||||
EXPECT_EQ(str.str(), "%42 = 4 | 2");
|
EXPECT_EQ(str.str(), "%42 = 4 | 2");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, CreateXor) {
|
TEST_F(IR_BinaryTest, CreateXor) {
|
||||||
auto& b = CreateEmptyBuilder();
|
auto& b = CreateEmptyBuilder();
|
||||||
|
|
||||||
b.builder.next_temp_id = Temp::Id(42);
|
b.builder.next_temp_id = Temp::Id(42);
|
||||||
|
@ -89,13 +85,11 @@ TEST_F(IR_InstructionTest, CreateXor) {
|
||||||
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
||||||
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||||
|
|
||||||
ASSERT_TRUE(instr->HasLHS());
|
|
||||||
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||||
auto lhs = instr->LHS()->As<Constant>();
|
auto lhs = instr->LHS()->As<Constant>();
|
||||||
ASSERT_TRUE(lhs->IsI32());
|
ASSERT_TRUE(lhs->IsI32());
|
||||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||||
|
|
||||||
ASSERT_TRUE(instr->HasRHS());
|
|
||||||
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||||
auto rhs = instr->RHS()->As<Constant>();
|
auto rhs = instr->RHS()->As<Constant>();
|
||||||
ASSERT_TRUE(rhs->IsI32());
|
ASSERT_TRUE(rhs->IsI32());
|
||||||
|
@ -106,7 +100,7 @@ TEST_F(IR_InstructionTest, CreateXor) {
|
||||||
EXPECT_EQ(str.str(), "%42 = 4 ^ 2");
|
EXPECT_EQ(str.str(), "%42 = 4 ^ 2");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, CreateLogicalAnd) {
|
TEST_F(IR_BinaryTest, CreateLogicalAnd) {
|
||||||
auto& b = CreateEmptyBuilder();
|
auto& b = CreateEmptyBuilder();
|
||||||
|
|
||||||
b.builder.next_temp_id = Temp::Id(42);
|
b.builder.next_temp_id = Temp::Id(42);
|
||||||
|
@ -118,13 +112,11 @@ TEST_F(IR_InstructionTest, CreateLogicalAnd) {
|
||||||
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
||||||
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||||
|
|
||||||
ASSERT_TRUE(instr->HasLHS());
|
|
||||||
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||||
auto lhs = instr->LHS()->As<Constant>();
|
auto lhs = instr->LHS()->As<Constant>();
|
||||||
ASSERT_TRUE(lhs->IsI32());
|
ASSERT_TRUE(lhs->IsI32());
|
||||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||||
|
|
||||||
ASSERT_TRUE(instr->HasRHS());
|
|
||||||
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||||
auto rhs = instr->RHS()->As<Constant>();
|
auto rhs = instr->RHS()->As<Constant>();
|
||||||
ASSERT_TRUE(rhs->IsI32());
|
ASSERT_TRUE(rhs->IsI32());
|
||||||
|
@ -135,7 +127,7 @@ TEST_F(IR_InstructionTest, CreateLogicalAnd) {
|
||||||
EXPECT_EQ(str.str(), "%42 = 4 && 2");
|
EXPECT_EQ(str.str(), "%42 = 4 && 2");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, CreateLogicalOr) {
|
TEST_F(IR_BinaryTest, CreateLogicalOr) {
|
||||||
auto& b = CreateEmptyBuilder();
|
auto& b = CreateEmptyBuilder();
|
||||||
|
|
||||||
b.builder.next_temp_id = Temp::Id(42);
|
b.builder.next_temp_id = Temp::Id(42);
|
||||||
|
@ -146,13 +138,11 @@ TEST_F(IR_InstructionTest, CreateLogicalOr) {
|
||||||
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
||||||
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||||
|
|
||||||
ASSERT_TRUE(instr->HasLHS());
|
|
||||||
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||||
auto lhs = instr->LHS()->As<Constant>();
|
auto lhs = instr->LHS()->As<Constant>();
|
||||||
ASSERT_TRUE(lhs->IsI32());
|
ASSERT_TRUE(lhs->IsI32());
|
||||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||||
|
|
||||||
ASSERT_TRUE(instr->HasRHS());
|
|
||||||
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||||
auto rhs = instr->RHS()->As<Constant>();
|
auto rhs = instr->RHS()->As<Constant>();
|
||||||
ASSERT_TRUE(rhs->IsI32());
|
ASSERT_TRUE(rhs->IsI32());
|
||||||
|
@ -163,7 +153,7 @@ TEST_F(IR_InstructionTest, CreateLogicalOr) {
|
||||||
EXPECT_EQ(str.str(), "%42 = 4 || 2");
|
EXPECT_EQ(str.str(), "%42 = 4 || 2");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, CreateEqual) {
|
TEST_F(IR_BinaryTest, CreateEqual) {
|
||||||
auto& b = CreateEmptyBuilder();
|
auto& b = CreateEmptyBuilder();
|
||||||
|
|
||||||
b.builder.next_temp_id = Temp::Id(42);
|
b.builder.next_temp_id = Temp::Id(42);
|
||||||
|
@ -174,13 +164,11 @@ TEST_F(IR_InstructionTest, CreateEqual) {
|
||||||
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
||||||
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||||
|
|
||||||
ASSERT_TRUE(instr->HasLHS());
|
|
||||||
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||||
auto lhs = instr->LHS()->As<Constant>();
|
auto lhs = instr->LHS()->As<Constant>();
|
||||||
ASSERT_TRUE(lhs->IsI32());
|
ASSERT_TRUE(lhs->IsI32());
|
||||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||||
|
|
||||||
ASSERT_TRUE(instr->HasRHS());
|
|
||||||
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||||
auto rhs = instr->RHS()->As<Constant>();
|
auto rhs = instr->RHS()->As<Constant>();
|
||||||
ASSERT_TRUE(rhs->IsI32());
|
ASSERT_TRUE(rhs->IsI32());
|
||||||
|
@ -191,7 +179,7 @@ TEST_F(IR_InstructionTest, CreateEqual) {
|
||||||
EXPECT_EQ(str.str(), "%42 = 4 == 2");
|
EXPECT_EQ(str.str(), "%42 = 4 == 2");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, CreateNotEqual) {
|
TEST_F(IR_BinaryTest, CreateNotEqual) {
|
||||||
auto& b = CreateEmptyBuilder();
|
auto& b = CreateEmptyBuilder();
|
||||||
|
|
||||||
b.builder.next_temp_id = Temp::Id(42);
|
b.builder.next_temp_id = Temp::Id(42);
|
||||||
|
@ -202,13 +190,11 @@ TEST_F(IR_InstructionTest, CreateNotEqual) {
|
||||||
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
||||||
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||||
|
|
||||||
ASSERT_TRUE(instr->HasLHS());
|
|
||||||
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||||
auto lhs = instr->LHS()->As<Constant>();
|
auto lhs = instr->LHS()->As<Constant>();
|
||||||
ASSERT_TRUE(lhs->IsI32());
|
ASSERT_TRUE(lhs->IsI32());
|
||||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||||
|
|
||||||
ASSERT_TRUE(instr->HasRHS());
|
|
||||||
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||||
auto rhs = instr->RHS()->As<Constant>();
|
auto rhs = instr->RHS()->As<Constant>();
|
||||||
ASSERT_TRUE(rhs->IsI32());
|
ASSERT_TRUE(rhs->IsI32());
|
||||||
|
@ -219,7 +205,7 @@ TEST_F(IR_InstructionTest, CreateNotEqual) {
|
||||||
EXPECT_EQ(str.str(), "%42 = 4 != 2");
|
EXPECT_EQ(str.str(), "%42 = 4 != 2");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, CreateLessThan) {
|
TEST_F(IR_BinaryTest, CreateLessThan) {
|
||||||
auto& b = CreateEmptyBuilder();
|
auto& b = CreateEmptyBuilder();
|
||||||
|
|
||||||
b.builder.next_temp_id = Temp::Id(42);
|
b.builder.next_temp_id = Temp::Id(42);
|
||||||
|
@ -230,13 +216,11 @@ TEST_F(IR_InstructionTest, CreateLessThan) {
|
||||||
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
||||||
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||||
|
|
||||||
ASSERT_TRUE(instr->HasLHS());
|
|
||||||
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||||
auto lhs = instr->LHS()->As<Constant>();
|
auto lhs = instr->LHS()->As<Constant>();
|
||||||
ASSERT_TRUE(lhs->IsI32());
|
ASSERT_TRUE(lhs->IsI32());
|
||||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||||
|
|
||||||
ASSERT_TRUE(instr->HasRHS());
|
|
||||||
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||||
auto rhs = instr->RHS()->As<Constant>();
|
auto rhs = instr->RHS()->As<Constant>();
|
||||||
ASSERT_TRUE(rhs->IsI32());
|
ASSERT_TRUE(rhs->IsI32());
|
||||||
|
@ -247,7 +231,7 @@ TEST_F(IR_InstructionTest, CreateLessThan) {
|
||||||
EXPECT_EQ(str.str(), "%42 = 4 < 2");
|
EXPECT_EQ(str.str(), "%42 = 4 < 2");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, CreateGreaterThan) {
|
TEST_F(IR_BinaryTest, CreateGreaterThan) {
|
||||||
auto& b = CreateEmptyBuilder();
|
auto& b = CreateEmptyBuilder();
|
||||||
|
|
||||||
b.builder.next_temp_id = Temp::Id(42);
|
b.builder.next_temp_id = Temp::Id(42);
|
||||||
|
@ -259,13 +243,11 @@ TEST_F(IR_InstructionTest, CreateGreaterThan) {
|
||||||
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
||||||
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||||
|
|
||||||
ASSERT_TRUE(instr->HasLHS());
|
|
||||||
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||||
auto lhs = instr->LHS()->As<Constant>();
|
auto lhs = instr->LHS()->As<Constant>();
|
||||||
ASSERT_TRUE(lhs->IsI32());
|
ASSERT_TRUE(lhs->IsI32());
|
||||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||||
|
|
||||||
ASSERT_TRUE(instr->HasRHS());
|
|
||||||
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||||
auto rhs = instr->RHS()->As<Constant>();
|
auto rhs = instr->RHS()->As<Constant>();
|
||||||
ASSERT_TRUE(rhs->IsI32());
|
ASSERT_TRUE(rhs->IsI32());
|
||||||
|
@ -276,7 +258,7 @@ TEST_F(IR_InstructionTest, CreateGreaterThan) {
|
||||||
EXPECT_EQ(str.str(), "%42 = 4 > 2");
|
EXPECT_EQ(str.str(), "%42 = 4 > 2");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, CreateLessThanEqual) {
|
TEST_F(IR_BinaryTest, CreateLessThanEqual) {
|
||||||
auto& b = CreateEmptyBuilder();
|
auto& b = CreateEmptyBuilder();
|
||||||
|
|
||||||
b.builder.next_temp_id = Temp::Id(42);
|
b.builder.next_temp_id = Temp::Id(42);
|
||||||
|
@ -288,13 +270,11 @@ TEST_F(IR_InstructionTest, CreateLessThanEqual) {
|
||||||
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
||||||
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||||
|
|
||||||
ASSERT_TRUE(instr->HasLHS());
|
|
||||||
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||||
auto lhs = instr->LHS()->As<Constant>();
|
auto lhs = instr->LHS()->As<Constant>();
|
||||||
ASSERT_TRUE(lhs->IsI32());
|
ASSERT_TRUE(lhs->IsI32());
|
||||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||||
|
|
||||||
ASSERT_TRUE(instr->HasRHS());
|
|
||||||
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||||
auto rhs = instr->RHS()->As<Constant>();
|
auto rhs = instr->RHS()->As<Constant>();
|
||||||
ASSERT_TRUE(rhs->IsI32());
|
ASSERT_TRUE(rhs->IsI32());
|
||||||
|
@ -305,7 +285,7 @@ TEST_F(IR_InstructionTest, CreateLessThanEqual) {
|
||||||
EXPECT_EQ(str.str(), "%42 = 4 <= 2");
|
EXPECT_EQ(str.str(), "%42 = 4 <= 2");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, CreateGreaterThanEqual) {
|
TEST_F(IR_BinaryTest, CreateGreaterThanEqual) {
|
||||||
auto& b = CreateEmptyBuilder();
|
auto& b = CreateEmptyBuilder();
|
||||||
|
|
||||||
b.builder.next_temp_id = Temp::Id(42);
|
b.builder.next_temp_id = Temp::Id(42);
|
||||||
|
@ -317,13 +297,11 @@ TEST_F(IR_InstructionTest, CreateGreaterThanEqual) {
|
||||||
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
||||||
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||||
|
|
||||||
ASSERT_TRUE(instr->HasLHS());
|
|
||||||
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||||
auto lhs = instr->LHS()->As<Constant>();
|
auto lhs = instr->LHS()->As<Constant>();
|
||||||
ASSERT_TRUE(lhs->IsI32());
|
ASSERT_TRUE(lhs->IsI32());
|
||||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||||
|
|
||||||
ASSERT_TRUE(instr->HasRHS());
|
|
||||||
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||||
auto rhs = instr->RHS()->As<Constant>();
|
auto rhs = instr->RHS()->As<Constant>();
|
||||||
ASSERT_TRUE(rhs->IsI32());
|
ASSERT_TRUE(rhs->IsI32());
|
||||||
|
@ -334,7 +312,7 @@ TEST_F(IR_InstructionTest, CreateGreaterThanEqual) {
|
||||||
EXPECT_EQ(str.str(), "%42 = 4 >= 2");
|
EXPECT_EQ(str.str(), "%42 = 4 >= 2");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, CreateShiftLeft) {
|
TEST_F(IR_BinaryTest, CreateShiftLeft) {
|
||||||
auto& b = CreateEmptyBuilder();
|
auto& b = CreateEmptyBuilder();
|
||||||
|
|
||||||
b.builder.next_temp_id = Temp::Id(42);
|
b.builder.next_temp_id = Temp::Id(42);
|
||||||
|
@ -345,13 +323,11 @@ TEST_F(IR_InstructionTest, CreateShiftLeft) {
|
||||||
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
||||||
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||||
|
|
||||||
ASSERT_TRUE(instr->HasLHS());
|
|
||||||
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||||
auto lhs = instr->LHS()->As<Constant>();
|
auto lhs = instr->LHS()->As<Constant>();
|
||||||
ASSERT_TRUE(lhs->IsI32());
|
ASSERT_TRUE(lhs->IsI32());
|
||||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||||
|
|
||||||
ASSERT_TRUE(instr->HasRHS());
|
|
||||||
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||||
auto rhs = instr->RHS()->As<Constant>();
|
auto rhs = instr->RHS()->As<Constant>();
|
||||||
ASSERT_TRUE(rhs->IsI32());
|
ASSERT_TRUE(rhs->IsI32());
|
||||||
|
@ -362,7 +338,7 @@ TEST_F(IR_InstructionTest, CreateShiftLeft) {
|
||||||
EXPECT_EQ(str.str(), "%42 = 4 << 2");
|
EXPECT_EQ(str.str(), "%42 = 4 << 2");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, CreateShiftRight) {
|
TEST_F(IR_BinaryTest, CreateShiftRight) {
|
||||||
auto& b = CreateEmptyBuilder();
|
auto& b = CreateEmptyBuilder();
|
||||||
|
|
||||||
b.builder.next_temp_id = Temp::Id(42);
|
b.builder.next_temp_id = Temp::Id(42);
|
||||||
|
@ -374,13 +350,11 @@ TEST_F(IR_InstructionTest, CreateShiftRight) {
|
||||||
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
||||||
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||||
|
|
||||||
ASSERT_TRUE(instr->HasLHS());
|
|
||||||
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||||
auto lhs = instr->LHS()->As<Constant>();
|
auto lhs = instr->LHS()->As<Constant>();
|
||||||
ASSERT_TRUE(lhs->IsI32());
|
ASSERT_TRUE(lhs->IsI32());
|
||||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||||
|
|
||||||
ASSERT_TRUE(instr->HasRHS());
|
|
||||||
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||||
auto rhs = instr->RHS()->As<Constant>();
|
auto rhs = instr->RHS()->As<Constant>();
|
||||||
ASSERT_TRUE(rhs->IsI32());
|
ASSERT_TRUE(rhs->IsI32());
|
||||||
|
@ -391,7 +365,7 @@ TEST_F(IR_InstructionTest, CreateShiftRight) {
|
||||||
EXPECT_EQ(str.str(), "%42 = 4 >> 2");
|
EXPECT_EQ(str.str(), "%42 = 4 >> 2");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, CreateAdd) {
|
TEST_F(IR_BinaryTest, CreateAdd) {
|
||||||
auto& b = CreateEmptyBuilder();
|
auto& b = CreateEmptyBuilder();
|
||||||
|
|
||||||
b.builder.next_temp_id = Temp::Id(42);
|
b.builder.next_temp_id = Temp::Id(42);
|
||||||
|
@ -402,13 +376,11 @@ TEST_F(IR_InstructionTest, CreateAdd) {
|
||||||
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
||||||
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||||
|
|
||||||
ASSERT_TRUE(instr->HasLHS());
|
|
||||||
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||||
auto lhs = instr->LHS()->As<Constant>();
|
auto lhs = instr->LHS()->As<Constant>();
|
||||||
ASSERT_TRUE(lhs->IsI32());
|
ASSERT_TRUE(lhs->IsI32());
|
||||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||||
|
|
||||||
ASSERT_TRUE(instr->HasRHS());
|
|
||||||
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||||
auto rhs = instr->RHS()->As<Constant>();
|
auto rhs = instr->RHS()->As<Constant>();
|
||||||
ASSERT_TRUE(rhs->IsI32());
|
ASSERT_TRUE(rhs->IsI32());
|
||||||
|
@ -419,7 +391,7 @@ TEST_F(IR_InstructionTest, CreateAdd) {
|
||||||
EXPECT_EQ(str.str(), "%42 = 4 + 2");
|
EXPECT_EQ(str.str(), "%42 = 4 + 2");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, CreateSubtract) {
|
TEST_F(IR_BinaryTest, CreateSubtract) {
|
||||||
auto& b = CreateEmptyBuilder();
|
auto& b = CreateEmptyBuilder();
|
||||||
|
|
||||||
b.builder.next_temp_id = Temp::Id(42);
|
b.builder.next_temp_id = Temp::Id(42);
|
||||||
|
@ -430,13 +402,11 @@ TEST_F(IR_InstructionTest, CreateSubtract) {
|
||||||
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
||||||
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||||
|
|
||||||
ASSERT_TRUE(instr->HasLHS());
|
|
||||||
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||||
auto lhs = instr->LHS()->As<Constant>();
|
auto lhs = instr->LHS()->As<Constant>();
|
||||||
ASSERT_TRUE(lhs->IsI32());
|
ASSERT_TRUE(lhs->IsI32());
|
||||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||||
|
|
||||||
ASSERT_TRUE(instr->HasRHS());
|
|
||||||
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||||
auto rhs = instr->RHS()->As<Constant>();
|
auto rhs = instr->RHS()->As<Constant>();
|
||||||
ASSERT_TRUE(rhs->IsI32());
|
ASSERT_TRUE(rhs->IsI32());
|
||||||
|
@ -447,7 +417,7 @@ TEST_F(IR_InstructionTest, CreateSubtract) {
|
||||||
EXPECT_EQ(str.str(), "%42 = 4 - 2");
|
EXPECT_EQ(str.str(), "%42 = 4 - 2");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, CreateMultiply) {
|
TEST_F(IR_BinaryTest, CreateMultiply) {
|
||||||
auto& b = CreateEmptyBuilder();
|
auto& b = CreateEmptyBuilder();
|
||||||
|
|
||||||
b.builder.next_temp_id = Temp::Id(42);
|
b.builder.next_temp_id = Temp::Id(42);
|
||||||
|
@ -458,13 +428,11 @@ TEST_F(IR_InstructionTest, CreateMultiply) {
|
||||||
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
||||||
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||||
|
|
||||||
ASSERT_TRUE(instr->HasLHS());
|
|
||||||
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||||
auto lhs = instr->LHS()->As<Constant>();
|
auto lhs = instr->LHS()->As<Constant>();
|
||||||
ASSERT_TRUE(lhs->IsI32());
|
ASSERT_TRUE(lhs->IsI32());
|
||||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||||
|
|
||||||
ASSERT_TRUE(instr->HasRHS());
|
|
||||||
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||||
auto rhs = instr->RHS()->As<Constant>();
|
auto rhs = instr->RHS()->As<Constant>();
|
||||||
ASSERT_TRUE(rhs->IsI32());
|
ASSERT_TRUE(rhs->IsI32());
|
||||||
|
@ -475,7 +443,7 @@ TEST_F(IR_InstructionTest, CreateMultiply) {
|
||||||
EXPECT_EQ(str.str(), "%42 = 4 * 2");
|
EXPECT_EQ(str.str(), "%42 = 4 * 2");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, CreateDivide) {
|
TEST_F(IR_BinaryTest, CreateDivide) {
|
||||||
auto& b = CreateEmptyBuilder();
|
auto& b = CreateEmptyBuilder();
|
||||||
|
|
||||||
b.builder.next_temp_id = Temp::Id(42);
|
b.builder.next_temp_id = Temp::Id(42);
|
||||||
|
@ -486,13 +454,11 @@ TEST_F(IR_InstructionTest, CreateDivide) {
|
||||||
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
||||||
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||||
|
|
||||||
ASSERT_TRUE(instr->HasLHS());
|
|
||||||
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||||
auto lhs = instr->LHS()->As<Constant>();
|
auto lhs = instr->LHS()->As<Constant>();
|
||||||
ASSERT_TRUE(lhs->IsI32());
|
ASSERT_TRUE(lhs->IsI32());
|
||||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||||
|
|
||||||
ASSERT_TRUE(instr->HasRHS());
|
|
||||||
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||||
auto rhs = instr->RHS()->As<Constant>();
|
auto rhs = instr->RHS()->As<Constant>();
|
||||||
ASSERT_TRUE(rhs->IsI32());
|
ASSERT_TRUE(rhs->IsI32());
|
||||||
|
@ -503,7 +469,7 @@ TEST_F(IR_InstructionTest, CreateDivide) {
|
||||||
EXPECT_EQ(str.str(), "%42 = 4 / 2");
|
EXPECT_EQ(str.str(), "%42 = 4 / 2");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IR_InstructionTest, CreateModulo) {
|
TEST_F(IR_BinaryTest, CreateModulo) {
|
||||||
auto& b = CreateEmptyBuilder();
|
auto& b = CreateEmptyBuilder();
|
||||||
|
|
||||||
b.builder.next_temp_id = Temp::Id(42);
|
b.builder.next_temp_id = Temp::Id(42);
|
||||||
|
@ -514,13 +480,11 @@ TEST_F(IR_InstructionTest, CreateModulo) {
|
||||||
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
ASSERT_TRUE(instr->Result()->Is<Temp>());
|
||||||
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
|
||||||
|
|
||||||
ASSERT_TRUE(instr->HasLHS());
|
|
||||||
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
ASSERT_TRUE(instr->LHS()->Is<Constant>());
|
||||||
auto lhs = instr->LHS()->As<Constant>();
|
auto lhs = instr->LHS()->As<Constant>();
|
||||||
ASSERT_TRUE(lhs->IsI32());
|
ASSERT_TRUE(lhs->IsI32());
|
||||||
EXPECT_EQ(i32(4), lhs->AsI32());
|
EXPECT_EQ(i32(4), lhs->AsI32());
|
||||||
|
|
||||||
ASSERT_TRUE(instr->HasRHS());
|
|
||||||
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
ASSERT_TRUE(instr->RHS()->Is<Constant>());
|
||||||
auto rhs = instr->RHS()->As<Constant>();
|
auto rhs = instr->RHS()->As<Constant>();
|
||||||
ASSERT_TRUE(rhs->IsI32());
|
ASSERT_TRUE(rhs->IsI32());
|
||||||
|
|
Loading…
Reference in New Issue