mirror of
https://github.com/lefticus/6502-cpp.git
synced 2024-12-21 10:30:35 +00:00
Enable option to disable optimization of 6502 assembly
- narrow down bug for optimized -O0 for 2d array writes
This commit is contained in:
parent
49cf9cc32d
commit
61e3609f47
@ -861,7 +861,7 @@ bool fix_long_branches(std::vector<mos6502> &instructions, int &branch_patch_cou
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector<mos6502> run(const Personality &personality, std::istream &input)
|
std::vector<mos6502> run(const Personality &personality, std::istream &input, const bool do_optimize)
|
||||||
{
|
{
|
||||||
std::regex Comment(R"(\s*(\#|;)(.*))");
|
std::regex Comment(R"(\s*(\#|;)(.*))");
|
||||||
std::regex Label(R"(^\s*(\S+):.*)");
|
std::regex Label(R"(^\s*(\S+):.*)");
|
||||||
@ -1038,8 +1038,19 @@ std::vector<mos6502> run(const Personality &personality, std::istream &input)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (optimize(new_instructions, personality)) {
|
if (do_optimize) {
|
||||||
// do it however many times it takes
|
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;
|
int branch_patch_count = 0;
|
||||||
@ -1060,6 +1071,7 @@ int main(const int argc, const char **argv)
|
|||||||
|
|
||||||
std::filesystem::path filename{};
|
std::filesystem::path filename{};
|
||||||
Target target{ Target::C64 };
|
Target target{ Target::C64 };
|
||||||
|
bool optimize{true};
|
||||||
|
|
||||||
app.add_option("-f,--file", filename, "C++ file to compile")->required(true);
|
app.add_option("-f,--file", filename, "C++ file to compile")->required(true);
|
||||||
app.add_option("-t,--target", target, "6502 - based system to target")
|
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")
|
app.add_option("-O", optimization_level, "Optimization level to pass to GCC instance")
|
||||||
->required(true)
|
->required(true)
|
||||||
->check(CLI::IsMember({ "s", "0", "1", "2", "3" }));
|
->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)
|
CLI11_PARSE(app, argc, argv)
|
||||||
@ -1113,7 +1128,7 @@ int main(const int argc, const char **argv)
|
|||||||
|
|
||||||
C64 personality;
|
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
|
// make sure file is closed before we try to re-open it with xa
|
||||||
|
@ -5,10 +5,12 @@
|
|||||||
|
|
||||||
enum struct OptimizationLevel : char { O0 = '0', O1 = '1', O2 = '2', O3 = '3', Os = 's' };
|
enum struct OptimizationLevel : char { O0 = '0', O1 = '1', O2 = '2', O3 = '3', Os = 's' };
|
||||||
|
|
||||||
|
enum struct Optimize6502 : char { Enabled = '1', Disabled = '0' };
|
||||||
|
|
||||||
std::vector<std::uint8_t> execute_c64_program(const std::string_view &name,
|
std::vector<std::uint8_t> execute_c64_program(const std::string_view &name,
|
||||||
const std::string_view script,
|
const std::string_view script,
|
||||||
[[maybe_unused]] OptimizationLevel o,
|
OptimizationLevel o,
|
||||||
|
Optimize6502 o6502,
|
||||||
std::uint16_t start_address_dump,
|
std::uint16_t start_address_dump,
|
||||||
std::uint16_t end_address_dump)
|
std::uint16_t end_address_dump)
|
||||||
{
|
{
|
||||||
@ -29,6 +31,16 @@ std::vector<std::uint8_t> execute_c64_program(const std::string_view &name,
|
|||||||
|
|
||||||
return "unknown";
|
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 source_filename{ fmt::format("{}{}.cpp", name, optimization_level) };
|
||||||
const auto vice_script_filename{ fmt::format("{}{}-vice_script", 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) };
|
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);
|
== EXIT_SUCCESS);
|
||||||
REQUIRE(
|
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);
|
== EXIT_SUCCESS);
|
||||||
|
|
||||||
std::ifstream memory_dump(ram_dump_filename, std::ios::binary);
|
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);
|
REQUIRE(result.size() == 1);
|
||||||
CHECK(result[0] == 10);
|
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);
|
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);
|
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",
|
TEMPLATE_TEST_CASE_SIG("Write to 2D Array",
|
||||||
"",
|
"",
|
||||||
((OptimizationLevel O), O),
|
((OptimizationLevel O, Optimize6502 O6502), O, O6502),
|
||||||
OptimizationLevel::Os,
|
(OptimizationLevel::Os, Optimize6502::Disabled),
|
||||||
OptimizationLevel::O0,
|
(OptimizationLevel::Os, Optimize6502::Enabled),
|
||||||
OptimizationLevel::O1,
|
(OptimizationLevel::O0, Optimize6502::Disabled),
|
||||||
OptimizationLevel::O2,
|
(OptimizationLevel::O0, Optimize6502::Enabled),
|
||||||
OptimizationLevel::O3)
|
(OptimizationLevel::O1, Optimize6502::Enabled),
|
||||||
|
(OptimizationLevel::O2, Optimize6502::Enabled),
|
||||||
|
(OptimizationLevel::O3, Optimize6502::Disabled),
|
||||||
|
(OptimizationLevel::O3, Optimize6502::Enabled))
|
||||||
{
|
{
|
||||||
constexpr static std::string_view program =
|
constexpr static std::string_view program =
|
||||||
R"(
|
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);
|
REQUIRE(result.size() == 1000);
|
||||||
|
|
||||||
for (std::size_t x = 0; x < 40; ++x) {
|
for (std::size_t x = 0; x < 40; ++x) {
|
||||||
for (std::size_t y = 0; y < 25; ++y) {
|
for (std::size_t y = 0; y < 25; ++y) { CHECK(result[y * 40 + x] == y); }
|
||||||
CHECK(result[y*40 + x] == y);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user