From 237bdc46441d74ff90deedeb4de405f7c79abf01 Mon Sep 17 00:00:00 2001 From: Emad Jacob Maroun Date: Tue, 6 Feb 2024 16:03:25 +0100 Subject: [PATCH] If bundled instructions both write to the same register, throw an error --- CMakeLists.txt | 2 +- src/simulation-core.cc | 36 +++++++++++++++++++++--------------- tests/CMakeLists.txt | 16 ++++++++++++++-- tests/test19.s | 3 ++- tests/test77.s | 11 +++++++++++ tests/test78.s | 14 ++++++++++++++ tests/test79.s | 19 +++++++++++++++++++ 7 files changed, 82 insertions(+), 19 deletions(-) create mode 100644 tests/test77.s create mode 100644 tests/test78.s create mode 100644 tests/test79.s diff --git a/CMakeLists.txt b/CMakeLists.txt index 23d35af..6b6d25f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -96,7 +96,7 @@ add_subdirectory(tests) # Save the target triple in a variable execute_process( COMMAND gcc -dumpmachine OUTPUT_VARIABLE DUMP_MACHINE OUTPUT_STRIP_TRAILING_WHITESPACE ) -message(WARNING "Machine Triple: ${DUMP_MACHINE}") +message(STATUS "Machine Triple: ${DUMP_MACHINE}") if (${DUMP_MACHINE} MATCHES "x86_64-linux-gnu") set( TARGET_TRIPLE "x86_64-linux-gnu") elseif(${DUMP_MACHINE} MATCHES "x86_64-apple-darwin.*") diff --git a/src/simulation-core.cc b/src/simulation-core.cc index 2457ed3..b5cd190 100644 --- a/src/simulation-core.cc +++ b/src/simulation-core.cc @@ -127,20 +127,26 @@ namespace patmos debug_out << pst << " : "; } - // Check permissive instructions - if( Use_permissive_dual_issue && f == &instruction_data_t::DR) { - assert(NUM_SLOTS = 2); - auto &pipe_instr0 = Pipeline[pst][0]; - auto &pipe_instr1 = Pipeline[pst][1]; - auto pred0 = PRR.get(pipe_instr0.Pred).get(); - auto pred1 = PRR.get(pipe_instr1.Pred).get(); + auto &pipe_instr0 = Pipeline[pst][0]; + auto &pipe_instr1 = Pipeline[pst][1]; + auto pred0 = PRR.get(pipe_instr0.Pred).get(); + auto pred1 = PRR.get(pipe_instr1.Pred).get(); + + if(pred0 && pred1 && f == &instruction_data_t::DR) { + boost::optional err; + + if(pipe_instr0.I->get_dst_reg(Pipeline[pst][0]) != patmos::GPR_e::r0 && + pipe_instr0.I->get_dst_reg(Pipeline[pst][0]) == pipe_instr1.I->get_dst_reg(Pipeline[pst][1]) + ){ + err = "register write"; + } else if(Use_permissive_dual_issue) { + assert(NUM_SLOTS = 2); #define is_combi(pred1, pred2) (\ (pipe_instr0.I->pred1() && pipe_instr1.I->pred2()) || \ (pipe_instr0.I->pred2() && pipe_instr1.I->pred1()) ) - if(pred0 && pred1) { - boost::optional err; + // Check permissive instructions if( is_combi(is_load, is_load) || is_combi(is_store, is_store) || is_combi(is_store, is_load) @@ -155,13 +161,13 @@ namespace patmos } else if(is_combi(is_multiply, is_multiply)) { err = "multiply"; } + } - if(err) { - auto msg = std::string("Two simultaneously enabled "); - msg.append(*err); - msg.append(" operations"); - patmos::simulation_exception_t::illegal(msg, Pipeline[pst][0]); - } + if(err) { + auto msg = std::string("Two simultaneously enabled "); + msg.append(*err); + msg.append(" operations"); + patmos::simulation_exception_t::illegal(msg, Pipeline[pst][0]); } } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index f567928..bfc0964 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -62,7 +62,7 @@ Errors : 0") test_asm(18 "Emitted: 28 bytes Errors : 0") -test_asm(19 "Emitted: 28 bytes +test_asm(19 "Emitted: 32 bytes Errors : 0") test_asm(21 "Emitted: 92 bytes @@ -201,6 +201,12 @@ test_asm(75 "Errors : 0") test_asm(76 "Errors : 0") +test_asm(77 "Errors : 0") + +test_asm(78 "Errors : 0") + +test_asm(79 "Errors : 0") + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # SIMULATOR TESTS # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # @@ -213,7 +219,7 @@ endmacro (test_sim) macro (test_sim_arg num args expr) ADD_TEST(sim-test-arg-${num} ${CMAKE_BINARY_DIR}/src/pasim -V --maxc 40000 -o - ${CMAKE_CURRENT_BINARY_DIR}/test${num}.bin ${args}) SET_TESTS_PROPERTIES(sim-test-arg-${num} PROPERTIES PASS_REGULAR_EXPRESSION ${expr} DEPENDS asm-test-${num}) -endmacro (test_sim) +endmacro (test_sim_arg) macro (test_dsim num expr) ADD_TEST(simd-test-${num} ${CMAKE_BINARY_DIR}/src/pasim -V -G 10 --maxc 40000 ${CMAKE_CURRENT_BINARY_DIR}/test${num}.bin) @@ -440,3 +446,9 @@ test_sim(74 "r1 : 00000539") test_sim(75 "\\\\\\[Error\\\\\\] Illegal instruction:.*00000008:.*invalid") test_sim(76 "r1 : 00000539") + +test_sim(77 "\\\\\\[Error\\\\\\] Illegal instruction: Two simultaneously enabled register write operations") + +test_sim(78 "r1 : 00000010.*r2 : 0000000b") + +test_sim(79 "r1 : 00000020") diff --git a/tests/test19.s b/tests/test19.s index e72b910..943b42c 100644 --- a/tests/test19.s +++ b/tests/test19.s @@ -3,7 +3,8 @@ # .word 28; - (p0) addi r1 = r0 , 5 || (p0) addi r1 = r0 , 7; + pand p1 = p0, !p0 + (p1) addi r1 = r0 , 5 || (p0) addi r1 = r0 , 7; halt; nop; nop; diff --git a/tests/test77.s b/tests/test77.s new file mode 100644 index 0000000..e283c57 --- /dev/null +++ b/tests/test77.s @@ -0,0 +1,11 @@ +# +# Tests two enabled instructions cannot be bundled if they write to the same register +# + + .word 100; + addi r1 = r0, 1 || addi r1 = r0, 2; + halt; + nop; + nop; + nop; + diff --git a/tests/test78.s b/tests/test78.s new file mode 100644 index 0000000..56f9482 --- /dev/null +++ b/tests/test78.s @@ -0,0 +1,14 @@ +# +# Tests bundled instructions can write to the same register if they are not both enabled. +# + + .word 100; + pand p1 = p0, p0; + pand p2 = p0, !p0; + (p1) addi r1 = r0, 16 || (p2) subi r1 = r0, 5; + (p2) addi r2 = r1, 16 || (p1) subi r2 = r1, 5; + halt; + nop; + nop; + nop; + diff --git a/tests/test79.s b/tests/test79.s new file mode 100644 index 0000000..7b380d9 --- /dev/null +++ b/tests/test79.s @@ -0,0 +1,19 @@ +# +# Tests bundled instructions can write to the same register if they are not both enabled. +# This test ensures that if the predicates where both enabled originally, and then one disabled +# right before the bundle, it will work correctly. +# +# I.e., this is a test that the pipelining is correctly accounted for in the check for the predicates and writes. +# + + .word 100; + pand p1 = p0, p0 || pand p2 = p0, p0; + pand p1 = p0, p0 || pand p2 = p0, p0; + pand p1 = p0, p0 || pand p2 = p0, p0; + pand p1 = p0, p0 || pand p2 = p0, !p0; + (p1) addi r1 = r0, 32 || (p2) subi r1 = r0, 5; + halt; + nop; + nop; + nop; +