| // Copyright 2023 Google LLC |
| // |
| // 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 |
| // |
| // https://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 "mpact/sim/generic/literal_operand.h" |
| |
| #include <memory> |
| |
| #include "absl/memory/memory.h" |
| #include "googlemock/include/gmock/gmock.h" |
| #include "googletest/include/gtest/gtest.h" |
| |
| namespace { |
| |
| using ::mpact::sim::generic::BoolLiteralOperand; |
| using ::mpact::sim::generic::BoolLiteralPredicateOperand; |
| using ::mpact::sim::generic::IntLiteralOperand; |
| |
| // Test BoolLiteralPredicateOperand<true>. |
| TEST(LiteralOperandTest, TrueBoolPredicateLiteral) { |
| BoolLiteralPredicateOperand<true> pred; |
| |
| EXPECT_TRUE(pred.Value()); |
| } |
| |
| // Test BoolLiteralPredciateOperand<false>. |
| TEST(LiteralOperandTest, FalseBoolPredicateLiteral) { |
| BoolLiteralPredicateOperand<false> pred; |
| |
| EXPECT_FALSE(pred.Value()); |
| } |
| |
| // Test BoolLiteralOperand<true> created from the default constructor. |
| TEST(LiteralOperandTest, TrueBoolLiteral) { |
| auto operand = std::make_unique<BoolLiteralOperand<true>>(); |
| |
| EXPECT_EQ(operand->shape().size(), 0); |
| EXPECT_EQ(operand->GetObject().has_value(), false); |
| EXPECT_EQ(operand->AsBool(0), true); |
| EXPECT_EQ(operand->AsInt8(0), 1); |
| EXPECT_EQ(operand->AsUint8(0), 1); |
| EXPECT_EQ(operand->AsInt16(0), 1); |
| EXPECT_EQ(operand->AsUint16(0), 1); |
| EXPECT_EQ(operand->AsInt32(0), 1); |
| EXPECT_EQ(operand->AsUint32(0), 1); |
| EXPECT_EQ(operand->AsInt64(0), 1); |
| EXPECT_EQ(operand->AsUint64(0), 1); |
| } |
| |
| // Test BoolLiteralOperand<false> created from the simple constructor. |
| TEST(LiteralOperandTest, FalseBoolLiteral) { |
| auto operand = std::make_unique<BoolLiteralOperand<false>>(); |
| |
| EXPECT_EQ(operand->shape().size(), 0); |
| EXPECT_EQ(operand->GetObject().has_value(), false); |
| EXPECT_EQ(operand->AsBool(0), false); |
| EXPECT_EQ(operand->AsInt8(0), 0); |
| EXPECT_EQ(operand->AsUint8(0), 0); |
| EXPECT_EQ(operand->AsInt16(0), 0); |
| EXPECT_EQ(operand->AsUint16(0), 0); |
| EXPECT_EQ(operand->AsInt32(0), 0); |
| EXPECT_EQ(operand->AsUint32(0), 0); |
| EXPECT_EQ(operand->AsInt64(0), 0); |
| EXPECT_EQ(operand->AsUint64(0), 0); |
| } |
| |
| // Test a "vector" immediate where shape is also given. |
| TEST(LiteralOperandTest, VectorBoolLiteral) { |
| auto operand = |
| std::make_unique<BoolLiteralOperand<true>>(std::vector<int>{128}); |
| |
| EXPECT_EQ(operand->shape().size(), 1); |
| EXPECT_THAT(operand->shape(), testing::ElementsAre(128)); |
| EXPECT_EQ(operand->GetObject().has_value(), false); |
| |
| for (int index = 0; index < 128; index += 16) { |
| EXPECT_EQ(operand->AsBool(index), true); |
| EXPECT_EQ(operand->AsInt8(index), 1); |
| EXPECT_EQ(operand->AsUint8(index), 1); |
| EXPECT_EQ(operand->AsInt16(index), 1); |
| EXPECT_EQ(operand->AsUint16(index), 1); |
| EXPECT_EQ(operand->AsInt32(index), 1); |
| EXPECT_EQ(operand->AsUint32(index), 1); |
| EXPECT_EQ(operand->AsInt64(index), 1); |
| EXPECT_EQ(operand->AsUint64(index), 1); |
| } |
| } |
| |
| // Test LiteralOperand created from the simple constructor (scalar). |
| TEST(LiteralOperandTest, IntLiteral) { |
| auto operand = std::make_unique<IntLiteralOperand<-123>>(); |
| |
| EXPECT_EQ(operand->shape().size(), 0); |
| EXPECT_EQ(operand->GetObject().has_value(), false); |
| EXPECT_EQ(operand->AsBool(0), true); |
| EXPECT_EQ(operand->AsInt8(0), -123); |
| EXPECT_EQ(operand->AsUint8(0), 133); // 2^8 - 123 |
| EXPECT_EQ(operand->AsInt16(0), -123); |
| EXPECT_EQ(operand->AsUint16(0), 65413); // 2^16 - 123 |
| EXPECT_EQ(operand->AsInt32(0), -123); |
| EXPECT_EQ(operand->AsUint32(0), 4294967173); // 2^32 - 123 |
| EXPECT_EQ(operand->AsInt64(0), -123); |
| EXPECT_EQ(operand->AsUint64(0), 18446744073709551493U); // 2^64 - 123 |
| } |
| |
| // Test that it always returns the same value even if index is outside |
| // that expected by the shape. |
| TEST(LiteralOperandTest, IntLiteralNonZeroIndex) { |
| auto operand = std::make_unique<IntLiteralOperand<123>>(); |
| |
| // The index doesn't matter. |
| EXPECT_EQ(operand->AsBool(4), true); |
| EXPECT_EQ(operand->AsInt8(4), 123); |
| EXPECT_EQ(operand->AsUint8(4), 123); |
| EXPECT_EQ(operand->AsInt16(4), 123); |
| EXPECT_EQ(operand->AsUint16(4), 123); |
| EXPECT_EQ(operand->AsInt32(4), 123); |
| EXPECT_EQ(operand->AsUint32(4), 123); |
| EXPECT_EQ(operand->AsInt64(4), 123); |
| EXPECT_EQ(operand->AsUint64(4), 123); |
| } |
| |
| // Test a "vector" literal where shape is also given. |
| TEST(LiteralOperandTest, VectorLiteral) { |
| auto operand = |
| std::make_unique<IntLiteralOperand<123>>(std::vector<int>{128}); |
| |
| EXPECT_EQ(operand->shape().size(), 1); |
| EXPECT_THAT(operand->shape(), testing::ElementsAre(128)); |
| EXPECT_EQ(operand->GetObject().has_value(), false); |
| |
| for (int index = 0; index < 128; index += 16) { |
| EXPECT_EQ(operand->AsBool(index), true); |
| EXPECT_EQ(operand->AsInt8(index), 123); |
| EXPECT_EQ(operand->AsUint8(index), 123); |
| EXPECT_EQ(operand->AsInt16(index), 123); |
| EXPECT_EQ(operand->AsUint16(index), 123); |
| EXPECT_EQ(operand->AsInt32(index), 123); |
| EXPECT_EQ(operand->AsUint32(index), 123); |
| EXPECT_EQ(operand->AsInt64(index), 123); |
| EXPECT_EQ(operand->AsUint64(index), 123); |
| } |
| } |
| } // namespace |