Commit d473b095 authored by phlo's avatar phlo

reverted to executing FENCE instructions

parent 695deddc
......@@ -21,15 +21,7 @@
// constructors
//------------------------------------------------------------------------------
Program::Program () :
set_fence(false),
num_removed(0)
{}
Program::Program(std::istream & f, const std::string & p) :
path(p),
set_fence(false),
num_removed(0)
Program::Program(std::istream & f, const std::string & p) : path(p)
{
std::string token;
......@@ -218,25 +210,6 @@ void Program::push_back (Instruction && op)
if (&op.symbol() == &Instruction::Check::symbol)
checkpoints[op.arg()].push_back(size());
// define the following instruction as memory barrier
if (&op.symbol() == &Instruction::Fence::symbol)
{
set_fence = true;
num_removed++;
return;
}
// define instruction as memory barrier
if (set_fence)
{
op.type(op.type() | Instruction::Type::barrier);
set_fence = false;
}
// adjust jump targets after removing FENCEs
if (op.is_jump() && num_removed)
op.arg(op.arg() - num_removed);
// append instruction
std::vector<Instruction>::push_back(op);
}
......@@ -282,29 +255,26 @@ std::string Program::print (const bool include_pc) const
std::string Program::print (const bool include_pc, const word_t pc) const
{
std::ostringstream ss;
const char delimiter = ' ';
if (include_pc)
ss << pc << delimiter;
// check if instruction is referenced by a label
auto label_it = pc_to_label.find(pc);
if (label_it != pc_to_label.end())
{
ss << *label_it->second;
if (include_pc)
ss << "\t";
else
ss << ": ";
}
else if (include_pc)
ss << pc << "\t";
ss << *label_it->second << ": ";
// instruction symbol
const Instruction & op = (*this)[pc];
ss << op.symbol() << "\t";
ss << op.symbol();
// print unary instruction's argument
if (op.is_unary())
{
ss << delimiter;
label_it = pc_to_label.find(op.arg());
if (op.is_jump() && label_it != pc_to_label.end())
{
......
......@@ -67,23 +67,13 @@ struct Program : public std::vector<Instruction>
//
std::unordered_set<std::string> labels;
// define next instruction as memory barrier
//
bool set_fence;
// adjust jump targets after removing FENCEs
//
word_t num_removed;
//----------------------------------------------------------------------------
// constructors
//----------------------------------------------------------------------------
using std::vector<Instruction>::vector; // inherit constructors
// default constructor
// inherit base constructors
//
Program ();
using std::vector<Instruction>::vector;
// construct from file
//
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
0 = data/increment.checker.asm
1 = data/increment.cas.asm
2 = data/increment.cas.asm
seed = 0
# tid pc cmd arg accu
0 0 CHECK 1 0
2 START MEM 1 0
2 1 ADDI 1 1
1 START MEM 1 0
1 1 ADDI 1 1
1 2 CAS 1 1
2 2 CAS 1 0
1 3 JZ START 1
1 4 CHECK 1 1
2 3 JZ START 0
2 START MEM 1 1
2 1 ADDI 1 2
2 2 CAS 1 1
2 3 JZ START 1
2 4 CHECK 1 1
0 1 LOAD 1 2
0 2 SUBI 2 0
0 3 JZ OK 0
0 OK EXIT 0 0
This diff is collapsed.
......@@ -6,15 +6,15 @@ data/increment.cas.asm
1 0 STORE 0 0 0 0 0 1 {}
1 0 FLUSH - 0 0 0 0 0 {(0,0)}
0 0 FLUSH - 0 0 0 0 0 {(0,0)}
1 1 CHECK 0 0 0 0 0 0 {}
0 1 CHECK 0 0 0 0 0 0 {}
0 LOOP MEM 0 0 0 0 0 0 {}
1 1 FENCE - 0 0 0 0 0 {}
0 1 FENCE - 0 0 0 0 0 {}
0 2 CHECK 0 0 0 0 0 0 {}
1 2 CHECK 0 0 0 0 0 0 {}
1 LOOP MEM 0 0 0 0 0 0 {}
1 3 ADDI 1 1 0 0 0 0 {}
0 3 ADDI 1 1 0 0 0 0 {}
0 4 CAS 0 1 0 0 0 0 {(0,1)}
0 5 JMP LOOP 1 0 0 0 0 {}
0 LOOP MEM 0 1 1 0 0 0 {}
1 4 CAS 0 0 0 0 0 0 {(0,1)}
1 5 JMP LOOP 0 0 0 0 0 {}
1 LOOP MEM 0 1 1 0 0 0 {}
0 LOOP MEM 0 0 0 0 0 0 {}
0 4 ADDI 1 1 0 0 0 0 {}
0 5 CAS 0 1 0 0 0 0 {(0,1)}
0 6 JMP LOOP 1 0 0 0 0 {}
1 4 ADDI 1 1 0 0 0 0 {}
1 5 CAS 0 0 0 0 0 0 {}
1 6 JMP LOOP 0 0 0 0 0 {}
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
......@@ -5,16 +5,16 @@ data/increment.check.thread.n.asm
0 0 STORE 0 0 0 0 0 1 {}
1 0 CHECK 0 0 0 0 0 0 {}
0 0 FLUSH - 0 0 0 0 0 {(0,0)}
0 1 CHECK 0 0 0 0 0 0 {}
0 2 LOAD 0 0 0 0 0 0 {}
0 1 FENCE - 0 0 0 0 0 {}
0 2 CHECK 0 0 0 0 0 0 {}
1 1 CHECK 1 0 0 0 0 0 {}
0 3 ADDI 1 1 0 0 0 0 {}
0 4 STORE 0 1 0 0 1 1 {}
0 4 FLUSH - 1 0 0 1 0 {(0,1)}
0 5 CHECK 1 1 0 0 1 0 {}
0 6 JNZ 1 1 0 0 1 0 {}
0 1 CHECK 0 1 0 0 1 0 {}
0 3 LOAD 0 0 0 0 0 0 {}
0 4 ADDI 1 1 0 0 0 0 {}
0 5 STORE 0 1 0 0 1 1 {}
0 6 CHECK 1 1 0 0 1 1 {}
0 7 JNZ 1 1 0 0 1 1 {}
0 7 FLUSH - 1 0 0 1 0 {(0,1)}
1 2 LOAD 0 1 0 0 0 0 {}
1 3 ADDI 1 2 0 0 0 0 {}
1 4 STORE 0 2 0 0 2 1 {}
1 4 FLUSH - 2 0 0 2 0 {(0,2)}
0 1 FENCE - 1 0 0 1 0 {}
......@@ -53,10 +53,10 @@ TEST_F(Encoder, constructor_flush_pcs)
reset_encoder();
for (const auto & p : *encoder->programs)
ASSERT_EQ(2, p.size());
ASSERT_EQ(3, p.size());
for (const auto & pcs : encoder->flush_pcs)
ASSERT_EQ(std::vector<word_t>({0, 1}), pcs.second);
ASSERT_EQ(std::vector<word_t>({0, 1, 2}), pcs.second);
}
TEST_F(Encoder, constructor_check_pcs)
......
......@@ -1405,15 +1405,15 @@ TEST_F(smtlib_Encoder, define_store_buffer_constraints)
"\n"
"(assert "
"(ite sb-full_1_0 "
"(=> (or stmt_1_0_0 stmt_1_0_1) (not thread_1_0)) "
"(=> (or stmt_1_0_0 stmt_1_0_1 stmt_1_0_2) (not thread_1_0)) "
"(not flush_1_0)))\n"
"(assert "
"(ite sb-full_1_1 "
"(=> (or stmt_1_1_0 stmt_1_1_1) (not thread_1_1)) "
"(=> (or stmt_1_1_0 stmt_1_1_1 stmt_1_1_2) (not thread_1_1)) "
"(not flush_1_1)))\n"
"(assert "
"(ite sb-full_1_2 "
"(=> (or stmt_1_2_0 stmt_1_2_1) (not thread_1_2)) "
"(=> (or stmt_1_2_0 stmt_1_2_1 stmt_1_2_2) (not thread_1_2)) "
"(not flush_1_2)))\n"
"\n",
encoder->str());
......@@ -1428,15 +1428,15 @@ TEST_F(smtlib_Encoder, define_store_buffer_constraints)
ASSERT_EQ(
"(assert "
"(ite sb-full_1_0 "
"(=> (or stmt_1_0_0 stmt_1_0_1) (not thread_1_0)) "
"(=> (or stmt_1_0_0 stmt_1_0_1 stmt_1_0_2) (not thread_1_0)) "
"(not flush_1_0)))\n"
"(assert "
"(ite sb-full_1_1 "
"(=> (or stmt_1_1_0 stmt_1_1_1) (not thread_1_1)) "
"(=> (or stmt_1_1_0 stmt_1_1_1 stmt_1_1_2) (not thread_1_1)) "
"(not flush_1_1)))\n"
"(assert "
"(ite sb-full_1_2 "
"(=> (or stmt_1_2_0 stmt_1_2_1) (not thread_1_2)) "
"(=> (or stmt_1_2_0 stmt_1_2_1 stmt_1_2_2) (not thread_1_2)) "
"(not flush_1_2)))\n"
"\n",
encoder->str());
......
......@@ -90,24 +90,22 @@ TEST_F(Program, parse)
{
program = create_from_file<::Program>("data/increment.cas.asm");
ASSERT_EQ(6, program.size());
ASSERT_EQ(7, program.size());
ASSERT_EQ(1, program.checkpoints.size());
ASSERT_EQ(1, program.checkpoints[0][0]);
ASSERT_EQ(2, program.checkpoints[0][0]);
ASSERT_EQ(1, program.labels.size());
ASSERT_EQ(1, program.pc_to_label.size());
ASSERT_EQ("LOOP", *program.pc_to_label[2]);
ASSERT_EQ("LOOP", *program.pc_to_label[3]);
ASSERT_EQ(1, program.label_to_pc.size());
ASSERT_EQ(2, program.label_to_pc[program.pc_to_label[2]]);
ASSERT_EQ(1, program.num_removed);
ASSERT_EQ("0\tSTORE\t0", program.print(true, 0));
ASSERT_EQ("1\tCHECK\t0", program.print(true, 1));
ASSERT_EQ("LOOP\tMEM\t0", program.print(true, 2));
ASSERT_EQ("3\tADDI\t1", program.print(true, 3));
ASSERT_EQ("4\tCAS\t0", program.print(true, 4));
ASSERT_EQ("5\tJMP\tLOOP", program.print(true, 5));
ASSERT_EQ(3, program.label_to_pc[program.pc_to_label[3]]);
ASSERT_TRUE(program[1].type() & Instruction::Type::barrier);
ASSERT_EQ("0 STORE 0", program.print(true, 0));
ASSERT_EQ("1 FENCE", program.print(true, 1));
ASSERT_EQ("2 CHECK 0", program.print(true, 2));
ASSERT_EQ("3 LOOP: MEM 0", program.print(true, 3));
ASSERT_EQ("4 ADDI 1", program.print(true, 4));
ASSERT_EQ("5 CAS 0", program.print(true, 5));
ASSERT_EQ("6 JMP LOOP", program.print(true, 6));
// indirect addressing
program = create_from_file<::Program>("data/indirect.addressing.asm");
......@@ -116,12 +114,12 @@ TEST_F(Program, parse)
ASSERT_EQ(0, program.checkpoints.size());
ASSERT_EQ(0, program.labels.size());
ASSERT_EQ("0\tSTORE\t1", program.print(true, 0));
ASSERT_EQ("1\tADDI\t1", program.print(true, 1));
ASSERT_EQ("2\tSTORE\t[1]", program.print(true, 2));
ASSERT_EQ("3\tLOAD\t[0]", program.print(true, 3));
ASSERT_EQ("4\tADD\t[1]", program.print(true, 4));
ASSERT_EQ("5\tCMP\t[1]", program.print(true, 5));
ASSERT_EQ("0 STORE 1", program.print(true, 0));
ASSERT_EQ("1 ADDI 1", program.print(true, 1));
ASSERT_EQ("2 STORE [1]", program.print(true, 2));
ASSERT_EQ("3 LOAD [0]", program.print(true, 3));
ASSERT_EQ("4 ADD [1]", program.print(true, 4));
ASSERT_EQ("5 CMP [1]", program.print(true, 5));
}
TEST_F(Program, parse_empty_line)
......@@ -133,8 +131,8 @@ TEST_F(Program, parse_empty_line)
ASSERT_EQ(2, program.size());
ASSERT_EQ("0\tADDI\t1", program.print(true, 0));
ASSERT_EQ("1\tEXIT\t1", program.print(true, 1));
ASSERT_EQ("0 ADDI 1", program.print(true, 0));
ASSERT_EQ("1 EXIT 1", program.print(true, 1));
}
TEST_F(Program, parse_file_not_found)
......@@ -392,6 +390,34 @@ TEST_F(Program, get_label)
}
}
// Program::print ==============================================================
TEST_F(Program, print)
{
program = create_from_file<::Program>("data/increment.cas.asm");
ASSERT_EQ(
"STORE 0\n"
"FENCE\n"
"CHECK 0\n"
"LOOP: MEM 0\n"
"ADDI 1\n"
"CAS 0\n"
"JMP LOOP\n",
program.print());
// include pc
ASSERT_EQ(
"0 STORE 0\n"
"1 FENCE\n"
"2 CHECK 0\n"
"3 LOOP: MEM 0\n"
"4 ADDI 1\n"
"5 CAS 0\n"
"6 JMP LOOP\n",
program.print(true));
}
// operator equals =============================================================
TEST_F(Program, operator_equals)
......
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