Commit 167b9651 authored by phlo's avatar phlo

updated Instruction's arity tests

parent d473b095
......@@ -6,33 +6,42 @@
#include "simulator.hh"
//==============================================================================
// Model<T>
// Model<POD>
//
// Instruction::Concept implementation
//==============================================================================
template <class T>
template <class POD>
constexpr bool is_nullary = std::is_base_of<Instruction::Nullary, POD>::value;
template <class POD>
constexpr bool is_unary = std::is_base_of<Instruction::Unary, POD>::value;
template <class POD>
constexpr bool is_memory = std::is_base_of<Instruction::Memory, POD>::value;
template <class POD>
constexpr bool is_jump = std::is_base_of<Instruction::Jmp, POD>::value;
template <class POD>
struct Model : Instruction::Concept
{
using Type = Instruction::Type;
using Nullary = Instruction::Nullary;
using Unary = Instruction::Unary;
using Memory = Instruction::Memory;
T pod;
POD pod;
Model (const T & p) : pod(p) {}
Model (const POD & p) : pod(p) {}
// Model (const T && pod) : obj(move(pod)) {}
std::unique_ptr<Concept> clone () const
{
return std::make_unique<Model<T>>(pod);
return std::make_unique<Model<POD>>(pod);
}
bool is_nullary () const { return std::is_base_of<Nullary, T>::value; }
bool is_unary () const { return std::is_base_of<Unary, T>::value; }
bool is_memory () const { return std::is_base_of<Memory, T>::value; }
bool is_jump () const { return pod.type & Instruction::Type::jump; }
bool is_nullary () const { return ::is_nullary<POD>; }
bool is_unary () const { return ::is_unary<POD>; }
bool is_memory () const { return ::is_memory<POD>; }
bool is_jump () const { return ::is_jump<POD>; }
bool requires_flush () const
{
......@@ -46,7 +55,7 @@ struct Model : Instruction::Concept
word_t arg () const
{
if constexpr(std::is_base_of<Unary, T>::value)
if constexpr(::is_unary<POD>)
return pod.arg;
else
{ assert(false); return 0; }
......@@ -54,7 +63,7 @@ struct Model : Instruction::Concept
void arg (const word_t a [[maybe_unused]])
{
if constexpr(std::is_base_of<Unary, T>::value)
if constexpr(::is_unary<POD>)
pod.arg = a;
else
assert(false);
......@@ -62,7 +71,7 @@ struct Model : Instruction::Concept
bool indirect () const
{
if constexpr(std::is_base_of<Memory, T>::value)
if constexpr(::is_memory<POD>)
return pod.indirect;
else
{ assert(false); return false; }
......@@ -70,7 +79,7 @@ struct Model : Instruction::Concept
void indirect (const bool i [[maybe_unused]])
{
if constexpr(std::is_base_of<Memory, T>::value)
if constexpr(::is_memory<POD>)
pod.indirect = i;
else
assert(false);
......
......@@ -114,21 +114,20 @@ struct Instruction
enum Type : uint8_t
{
none = 0,
accu = 1 << 0, // modifies accu
mem = 1 << 1, // modifies mem
accu = 1 << 0, // modifies accu
mem = 1 << 1, // modifies mem
modify = accu | mem, // modifies a register
read = 1 << 2, // reads from memory
write = 1 << 3, // writes to memory
atomic = 1 << 4, // atomic instruction
barrier = 1 << 5, // memory barrier
control = 1 << 6, // control flow
jump = 1 << 7 // jump instruction
read = 1 << 2, // reads from memory
write = 1 << 3, // writes to memory
atomic = 1 << 4, // atomic instruction
barrier = 1 << 5, // memory barrier
control = 1 << 6 // control flow
};
// instruction PODs ----------------------------------------------------------
//
struct Nullary { uint8_t type = Type::none; };
struct Unary : Nullary { word_t arg; };
struct Unary : Nullary { word_t arg = 0; };
struct Memory : Unary { bool indirect = false; };
DECLARE_MEMORY (Load, Memory, "LOAD", accu | read)
......@@ -144,12 +143,12 @@ struct Instruction
DECLARE_UNARY (Muli, Unary, "MULI", accu)
DECLARE_MEMORY (Cmp, Load, "CMP", accu | read)
DECLARE_UNARY (Jmp, Unary, "JMP", control | jump)
DECLARE_UNARY (Jz, Jmp, "JZ", control | jump)
DECLARE_UNARY (Jnz, Jmp, "JNZ", control | jump)
DECLARE_UNARY (Js, Jmp, "JS", control | jump)
DECLARE_UNARY (Jns, Jmp, "JNS", control | jump)
DECLARE_UNARY (Jnzns, Jmp, "JNZNS", control | jump)
DECLARE_UNARY (Jmp, Unary, "JMP", control)
DECLARE_UNARY (Jz, Jmp, "JZ", control)
DECLARE_UNARY (Jnz, Jmp, "JNZ", control)
DECLARE_UNARY (Js, Jmp, "JS", control)
DECLARE_UNARY (Jns, Jmp, "JNS", control)
DECLARE_UNARY (Jnzns, Jmp, "JNZNS", control)
DECLARE_MEMORY (Mem, Load, "MEM", accu | mem | read)
DECLARE_MEMORY (Cas, Store, "CAS", accu | read | atomic | barrier)
......
......@@ -730,13 +730,16 @@ const std::optional<Schedule::Heap> Schedule::iterator::next_heap_state ()
auto & cell = heap.at(address);
// mind subsequent writes of an equal value to the same address
word_t value =
cell.cur->first == step
? cell.cur++->second
: (--cell.cur)++->second;
if (cell.cur->first == step)
{
// mind subsequent writes of an equal value to the same address
word_t value =
cell.cur->first == step
? cell.cur++->second
: (--cell.cur)++->second;
return {{address, value}};
return {{address, value}};
}
}
return {};
......
......@@ -152,12 +152,7 @@ Schedule::ptr Simulator::run (std::function<Thread *()> scheduler)
}
// exiting - return exit code
case Thread::State::exited:
{
done = true;
schedule->exit = static_cast<int>(thread->accu);
break;
}
case Thread::State::exited: done = true; break;
default:
{
......@@ -486,15 +481,16 @@ void Thread::execute (const Instruction::Check & c)
PUSH_BACK(pc++);
}
// TODO
void Thread::execute (const Instruction::Halt & h [[maybe_unused]])
{
PUSH_BACK(pc++);
state = State::halted;
PUSH_BACK(pc);
}
void Thread::execute (const Instruction::Exit & e)
{
accu = e.arg;
simulator.schedule->exit = e.arg;
state = State::exited;
PUSH_BACK(pc);
......
......@@ -36,7 +36,6 @@ TEST_RUN := run_all_tests
GTEST_FILTER = --gtest_filter=
# GTEST_FILTER += "*"
# GTEST_FILTER += *Encoder*
GTEST_FILTER += Encoder.*
GTEST_FILTER += smtlib.*
GTEST_FILTER += smtlib_Encoder.*
......@@ -44,7 +43,7 @@ GTEST_FILTER += smtlib_Functional.*
GTEST_FILTER += smtlib_Relational.*
GTEST_FILTER += btor2.*
GTEST_FILTER += btor2_Encoder.*
GTEST_FILTER += Thread.*
# GTEST_FILTER += Thread.*
# GTEST_FILTER += Simulator.*
# GTEST_FILTER += Main.*
# GTEST_FILTER += Experimental.*
......
......@@ -501,7 +501,7 @@ TEST_F(Instruction, JMP)
ASSERT_FALSE(instruction.requires_flush());
ASSERT_EQ("JMP", instruction.symbol());
ASSERT_EQ(Type::control | Type::jump, instruction.type());
ASSERT_EQ(Type::control, instruction.type());
ASSERT_EQ(word_max, instruction.arg());
ASSERT_EQ(0, thread.pc);
......@@ -530,7 +530,7 @@ TEST_F(Instruction, JZ)
ASSERT_FALSE(instruction.requires_flush());
ASSERT_EQ("JZ", instruction.symbol());
ASSERT_EQ(Type::control | Type::jump, instruction.type());
ASSERT_EQ(Type::control, instruction.type());
ASSERT_EQ(0, instruction.arg());
ASSERT_EQ(0, thread.pc);
......@@ -560,7 +560,7 @@ TEST_F(Instruction, JNZ)
ASSERT_FALSE(instruction.requires_flush());
ASSERT_EQ("JNZ", instruction.symbol());
ASSERT_EQ(Type::control | Type::jump, instruction.type());
ASSERT_EQ(Type::control, instruction.type());
ASSERT_EQ(0, instruction.arg());
ASSERT_EQ(0, thread.pc);
......@@ -590,7 +590,7 @@ TEST_F(Instruction, JS)
ASSERT_FALSE(instruction.requires_flush());
ASSERT_EQ("JS", instruction.symbol());
ASSERT_EQ(Type::control | Type::jump, instruction.type());
ASSERT_EQ(Type::control, instruction.type());
ASSERT_EQ(0, instruction.arg());
ASSERT_EQ(0, thread.pc);
......@@ -620,7 +620,7 @@ TEST_F(Instruction, JNS)
ASSERT_FALSE(instruction.requires_flush());
ASSERT_EQ("JNS", instruction.symbol());
ASSERT_EQ(Type::control | Type::jump, instruction.type());
ASSERT_EQ(Type::control, instruction.type());
ASSERT_EQ(0, instruction.arg());
ASSERT_EQ(0, thread.pc);
......@@ -650,7 +650,7 @@ TEST_F(Instruction, JNZNS)
ASSERT_FALSE(instruction.requires_flush());
ASSERT_EQ("JNZNS", instruction.symbol());
ASSERT_EQ(Type::control | Type::jump, instruction.type());
ASSERT_EQ(Type::control, instruction.type());
ASSERT_EQ(0, instruction.arg());
ASSERT_EQ(0, thread.pc);
......@@ -811,7 +811,8 @@ TEST_F(Instruction, EXIT)
instruction.execute(thread);
ASSERT_EQ(0, thread.pc);
ASSERT_EQ(1, thread.accu);
ASSERT_EQ(0, thread.accu);
ASSERT_EQ(1, thread.simulator.schedule->exit);
ASSERT_EQ(Thread::State::exited, thread.state);
}
......
......@@ -116,10 +116,10 @@ TEST_F(Simulator, run_simple)
// run it
schedule = simulator->run(scheduler);
EXPECT_EQ(2, step);
ASSERT_EQ(2, step);
EXPECT_EQ(Thread::State::halted, simulator->threads[0].state);
EXPECT_EQ(Thread::State::halted, simulator->threads[1].state);
ASSERT_EQ(Thread::State::halted, simulator->threads[0].state);
ASSERT_EQ(Thread::State::halted, simulator->threads[1].state);
// check Schedule
ASSERT_EQ(0, schedule->exit);
......@@ -235,10 +235,10 @@ TEST_F(Simulator, run_add_check_exit)
// run it
schedule = simulator->run(scheduler);
EXPECT_EQ(step, 5);
ASSERT_EQ(step, 5);
EXPECT_EQ(Thread::State::exited, simulator->threads[0].state);
EXPECT_EQ(Thread::State::running, simulator->threads[1].state);
ASSERT_EQ(Thread::State::exited, simulator->threads[0].state);
ASSERT_EQ(Thread::State::running, simulator->threads[1].state);
// check Schedule
ASSERT_EQ(1, schedule->exit);
......@@ -535,11 +535,11 @@ TEST_F(Simulator, run_race_condition)
// run it
schedule = simulator->run(scheduler);
EXPECT_EQ(15, step);
ASSERT_EQ(15, step);
EXPECT_EQ(Thread::State::exited, simulator->threads[0].state);
EXPECT_EQ(Thread::State::halted, simulator->threads[1].state);
EXPECT_EQ(Thread::State::halted, simulator->threads[2].state);
ASSERT_EQ(Thread::State::exited, simulator->threads[0].state);
ASSERT_EQ(Thread::State::halted, simulator->threads[1].state);
ASSERT_EQ(Thread::State::halted, simulator->threads[2].state);
// check Schedule
ASSERT_EQ(1, schedule->exit);
......@@ -553,7 +553,7 @@ TEST_F(Simulator, run_race_condition)
ASSERT_EQ(
Schedule::Thread_Updates<word_t>({
{{1, 0}, {12, 1}, {13, 65535}, {15, 1}},
{{1, 0}, {12, 1}, {13, 65535}},
{{2, 0}, {4, 1}},
{{3, 0}, {5, 1}}}),
schedule->accu_updates);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment