diff --git a/src/6502-c++.cpp b/src/6502-c++.cpp index 15eabbb..7d60862 100644 --- a/src/6502-c++.cpp +++ b/src/6502-c++.cpp @@ -861,7 +861,7 @@ bool fix_long_branches(std::vector &instructions, int &branch_patch_cou } -std::vector run(const Personality &personality, std::istream &input) +std::vector run(const Personality &personality, std::istream &input, const bool do_optimize) { std::regex Comment(R"(\s*(\#|;)(.*))"); std::regex Label(R"(^\s*(\S+):.*)"); @@ -1038,8 +1038,19 @@ std::vector run(const Personality &personality, std::istream &input) } } - while (optimize(new_instructions, personality)) { - // do it however many times it takes + if (do_optimize) { + spdlog::info("Running optimization passes"); + + int count = 0; + + while (optimize(new_instructions, personality)) { + // do it however many times it takes + ++count; + } + + spdlog::info("Optimization passes run: {}", count); + } else { + spdlog::info("Optimization passes disabled"); } int branch_patch_count = 0; @@ -1060,6 +1071,7 @@ int main(const int argc, const char **argv) std::filesystem::path filename{}; Target target{ Target::C64 }; + bool optimize{true}; app.add_option("-f,--file", filename, "C++ file to compile")->required(true); app.add_option("-t,--target", target, "6502 - based system to target") @@ -1070,6 +1082,9 @@ int main(const int argc, const char **argv) app.add_option("-O", optimization_level, "Optimization level to pass to GCC instance") ->required(true) ->check(CLI::IsMember({ "s", "0", "1", "2", "3" })); + app.add_flag("--optimize", optimize, "Enable optimization of 6502 generated assembly") + ->default_val(true); + CLI11_PARSE(app, argc, argv) @@ -1113,7 +1128,7 @@ int main(const int argc, const char **argv) C64 personality; - const auto new_instructions = run(personality, input); + const auto new_instructions = run(personality, input, optimize); { // make sure file is closed before we try to re-open it with xa diff --git a/test/tests.cpp b/test/tests.cpp index b32f9b2..946b719 100644 --- a/test/tests.cpp +++ b/test/tests.cpp @@ -5,10 +5,12 @@ enum struct OptimizationLevel : char { O0 = '0', O1 = '1', O2 = '2', O3 = '3', Os = 's' }; +enum struct Optimize6502 : char { Enabled = '1', Disabled = '0' }; std::vector execute_c64_program(const std::string_view &name, const std::string_view script, - [[maybe_unused]] OptimizationLevel o, + OptimizationLevel o, + Optimize6502 o6502, std::uint16_t start_address_dump, std::uint16_t end_address_dump) { @@ -29,6 +31,16 @@ std::vector execute_c64_program(const std::string_view &name, return "unknown"; }(); + + const auto optimize_6502 = [&]() -> std::string_view { + switch (o6502) { + case Optimize6502::Enabled: return "--optimize=1"; + case Optimize6502::Disabled: return "--optimize=0"; + } + + return "unknown"; + }(); + const auto source_filename{ fmt::format("{}{}.cpp", name, optimization_level) }; const auto vice_script_filename{ fmt::format("{}{}-vice_script", name, optimization_level) }; const auto prg_filename{ fmt::format("{}{}.prg", name, optimization_level) }; @@ -58,10 +70,14 @@ quit } - REQUIRE(system(fmt::format("{} -f {} -t C64 {}", mos6502_cpp_executable, source_filename, optimization_level).c_str()) + REQUIRE(system(fmt::format( + "{} -f {} -t C64 {} {}", mos6502_cpp_executable, source_filename, optimization_level, optimize_6502) + .c_str()) == EXIT_SUCCESS); REQUIRE( - system(fmt::format("xvfb-run -d {} +vsync -sounddev dummy +saveres -warp -moncommands {}", x64_executable, vice_script_filename).c_str()) + system(fmt::format( + "xvfb-run -d {} +vsync -sounddev dummy +saveres -warp -moncommands {}", x64_executable, vice_script_filename) + .c_str()) == EXIT_SUCCESS); std::ifstream memory_dump(ram_dump_filename, std::ios::binary); @@ -91,7 +107,7 @@ int main() } )"; - const auto result = execute_c64_program("write_to_memory", program, O, 0x400, 0x400); + const auto result = execute_c64_program("write_to_memory", program, O, Optimize6502::Enabled, 0x400, 0x400); REQUIRE(result.size() == 1); CHECK(result[0] == 10); @@ -121,7 +137,8 @@ int main() )"; - const auto result = execute_c64_program("write_to_memory_via_function", program, O, 0x400, 0x401); + const auto result = + execute_c64_program("write_to_memory_via_function", program, O, Optimize6502::Enabled, 0x400, 0x401); REQUIRE(result.size() == 2); @@ -155,21 +172,24 @@ int main() )"; - const auto result = execute_c64_program("execute_long_loop_cls", program, O, 0x400, 0x7E7); + const auto result = execute_c64_program("execute_long_loop_cls", program, O, Optimize6502::Enabled, 0x400, 0x7E7); REQUIRE(result.size() == 1000); - CHECK(std::all_of(begin(result), end(result), [](const auto b){ return b == 32; })); + CHECK(std::all_of(begin(result), end(result), [](const auto b) { return b == 32; })); } TEMPLATE_TEST_CASE_SIG("Write to 2D Array", "", - ((OptimizationLevel O), O), - OptimizationLevel::Os, - OptimizationLevel::O0, - OptimizationLevel::O1, - OptimizationLevel::O2, - OptimizationLevel::O3) + ((OptimizationLevel O, Optimize6502 O6502), O, O6502), + (OptimizationLevel::Os, Optimize6502::Disabled), + (OptimizationLevel::Os, Optimize6502::Enabled), + (OptimizationLevel::O0, Optimize6502::Disabled), + (OptimizationLevel::O0, Optimize6502::Enabled), + (OptimizationLevel::O1, Optimize6502::Enabled), + (OptimizationLevel::O2, Optimize6502::Enabled), + (OptimizationLevel::O3, Optimize6502::Disabled), + (OptimizationLevel::O3, Optimize6502::Enabled)) { constexpr static std::string_view program = R"( @@ -199,13 +219,11 @@ int main() )"; - const auto result = execute_c64_program("write_to_2d_array", program, O, 0x400, 0x7E7); + const auto result = execute_c64_program("write_to_2d_array", program, O, O6502, 0x400, 0x7E7); REQUIRE(result.size() == 1000); for (std::size_t x = 0; x < 40; ++x) { - for (std::size_t y = 0; y < 25; ++y) { - CHECK(result[y*40 + x] == y); - } + for (std::size_t y = 0; y < 25; ++y) { CHECK(result[y * 40 + x] == y); } } }