Add capture regs from Chip Data File to IsolationNode
Change-Id: Ia91821f2b14e12ed917c97b622789710ffb8bdb4
Signed-off-by: Zane Shelley <zshelle@us.ibm.com>
diff --git a/test/operator_register_test.cpp b/test/operator_register_test.cpp
new file mode 100644
index 0000000..227a566
--- /dev/null
+++ b/test/operator_register_test.cpp
@@ -0,0 +1,152 @@
+#include <hei_chip.hpp>
+#include <register/hei_operator_register.hpp>
+#include <util/hei_flyweight.hpp>
+
+#include "gtest/gtest.h"
+
+using namespace libhei;
+
+constexpr uint16_t CONST1 = 0x1458;
+constexpr uint16_t CONST2 = 0x5368;
+
+#define MATH(x) static_cast<uint16_t>(x)
+
+uint64_t __getVal(Register::ConstPtr i_reg)
+{
+ Chip CHIP{nullptr, 0};
+ auto bs = i_reg->getBitString(CHIP);
+ return bs->getFieldRight(0, bs->getBitLen());
+}
+
+size_t __getBW(Register::ConstPtr i_reg)
+{
+ Chip CHIP{nullptr, 0};
+ return i_reg->getBitString(CHIP)->getBitLen();
+}
+
+TEST(OperatorRegisterTest, BasicOperations)
+{
+ auto const1 = std::make_shared<const ConstantRegister>(CONST1);
+ ASSERT_EQ(MATH(CONST1), __getVal(const1));
+
+ auto const2 = std::make_shared<const ConstantRegister>(CONST2);
+ ASSERT_EQ(MATH(CONST2), __getVal(const2));
+
+ auto and1 = std::make_shared<const AndRegister>(const1, const2);
+ ASSERT_EQ(MATH(CONST1 & CONST2), __getVal(and1));
+
+ auto or1 = std::make_shared<const OrRegister>(const1, const2);
+ ASSERT_EQ(MATH(CONST1 | CONST2), __getVal(or1));
+
+ auto not1 = std::make_shared<const NotRegister>(const1);
+ ASSERT_EQ(MATH(~CONST1), __getVal(not1));
+
+ auto not2 = std::make_shared<const NotRegister>(const2);
+ ASSERT_EQ(MATH(~CONST2), __getVal(not2));
+}
+
+TEST(OperatorRegisterTest, BasicOperationsWithFlyweights)
+{
+ auto& const_factory = Flyweight<const ConstantRegister>::getSingleton();
+ auto& and_factory = Flyweight<const AndRegister>::getSingleton();
+ auto& or_factory = Flyweight<const OrRegister>::getSingleton();
+ auto& not_factory = Flyweight<const NotRegister>::getSingleton();
+
+ auto const1 = const_factory.get(CONST1);
+ auto const2 = const_factory.get(CONST2);
+
+ ASSERT_EQ(MATH(CONST1), __getVal(const1));
+ ASSERT_EQ(MATH(CONST2), __getVal(const2));
+ ASSERT_EQ(MATH(CONST1 & CONST2), __getVal(and_factory.get(const1, const2)));
+ ASSERT_EQ(MATH(CONST1 | CONST2), __getVal(or_factory.get(const1, const2)));
+ ASSERT_EQ(MATH(~CONST1), __getVal(not_factory.get(const1)));
+ ASSERT_EQ(MATH(~CONST2), __getVal(not_factory.get(const2)));
+
+ const_factory.clear();
+ and_factory.clear();
+ or_factory.clear();
+ not_factory.clear();
+}
+
+TEST(OperatorRegisterTest, ShiftOperations)
+{
+ auto& const_factory = Flyweight<const ConstantRegister>::getSingleton();
+ auto& lshift_factory = Flyweight<const LeftShiftRegister>::getSingleton();
+ auto& rshift_factory = Flyweight<const RightShiftRegister>::getSingleton();
+
+ auto const1 = const_factory.get(CONST1);
+
+ for (size_t i = 0; i < __getBW(const1); i++)
+ {
+ ASSERT_EQ(MATH(CONST1 << i), __getVal(lshift_factory.get(const1, i)));
+ }
+
+ for (size_t i = 0; i < __getBW(const1); i++)
+ {
+ ASSERT_EQ(MATH(CONST1 >> i), __getVal(rshift_factory.get(const1, i)));
+ }
+
+ const_factory.clear();
+ lshift_factory.clear();
+ rshift_factory.clear();
+}
+
+TEST(OperatorRegisterTest, ComplexOperation)
+{
+ // Something seemingly complex:
+ // ~(((CONST1 & CONST2) << 12) | ((CONST1 | CONST2) >> 4)))
+
+ auto& const_factory = Flyweight<const ConstantRegister>::getSingleton();
+ auto& and_factory = Flyweight<const AndRegister>::getSingleton();
+ auto& or_factory = Flyweight<const OrRegister>::getSingleton();
+ auto& not_factory = Flyweight<const NotRegister>::getSingleton();
+ auto& lshift_factory = Flyweight<const LeftShiftRegister>::getSingleton();
+ auto& rshift_factory = Flyweight<const RightShiftRegister>::getSingleton();
+
+ auto const1 = const_factory.get(CONST1);
+ auto const2 = const_factory.get(CONST2);
+
+ auto lshift = lshift_factory.get(and_factory.get(const1, const2), 12);
+ auto rshift = rshift_factory.get(or_factory.get(const1, const2), 4);
+
+ auto expr = not_factory.get(or_factory.get(lshift, rshift));
+
+ ASSERT_EQ(MATH(~(((CONST1 & CONST2) << 12) | ((CONST1 | CONST2) >> 4))),
+ __getVal(expr));
+
+ const_factory.clear();
+ and_factory.clear();
+ or_factory.clear();
+ not_factory.clear();
+ lshift_factory.clear();
+ rshift_factory.clear();
+}
+
+TEST(OperatorRegisterTest, ConstRegConstructor)
+{
+ auto& const_factory = Flyweight<const ConstantRegister>::getSingleton();
+ auto& and_factory = Flyweight<const AndRegister>::getSingleton();
+
+ // The ConstRegister constructor is a template that requires some integer
+ // type.
+
+ auto const1 = const_factory.get(CONST1); // CONST1 is uint16_t, GOOD
+
+ auto const2 = const_factory.get(uint16_t{0x1458}); // This also works
+
+ ASSERT_EQ(const1, const2); // Should point to the same thing.
+
+ // If you pass in a constant with no type the compiler assumes it is the
+ // implicit int type. This value is the same as const2, but the size will be
+ // different.
+ auto const3 = const_factory.get(0x1458);
+
+ // The values are the same, but the bit strings are are different sizes.
+ ASSERT_NE(const2, const3);
+
+ // AND and OR operators will not like different sizes either.
+ ASSERT_DEATH(and_factory.get(const2, const3), "");
+
+ const_factory.clear();
+ and_factory.clear();
+}