From 922d5b3c81459173ce99970dca0e44825f0a4494 Mon Sep 17 00:00:00 2001 From: AJR Date: Wed, 16 Nov 2022 18:36:52 -0500 Subject: Make numbers signed in debugger where it matters - Perform signed calculations for /, %, >>, /=, %=, >>=, <, >, <=, >= operators in debugger expressions - Eliminate workarounds in debugger printf method for system printf not reliably handling 64-bit integers (a previous refactoring adopted strformat for this) - Output signed decimals for %d in debugger printf formats; also add %u format - Add two-argument sext function to debugger --- src/emu/debug/debugcmd.cpp | 40 +++++++++++++++++++--------------------- src/emu/debug/express.cpp | 20 ++++++++++---------- 2 files changed, 29 insertions(+), 31 deletions(-) diff --git a/src/emu/debug/debugcmd.cpp b/src/emu/debug/debugcmd.cpp index 4ccb88fbe20..25f2ce5fbeb 100644 --- a/src/emu/debug/debugcmd.cpp +++ b/src/emu/debug/debugcmd.cpp @@ -151,6 +151,9 @@ debugger_commands::debugger_commands(running_machine& machine, debugger_cpu& cpu symtable.add("s32", 1, 1, // sign-extend from 32 bits [] (int params, const u64 *param) -> u64 { return s64(s32(u32(param[0]))); }); + symtable.add("sext", 2, 2, // sign-extend from any width + [] (int params, const u64 *param) -> u64 + { return util::sext(param[0], param[1]); }); symtable.add("cpunum", std::bind(&debugger_commands::get_cpunum, this)); // add all single-entry save state globals @@ -521,11 +524,7 @@ bool debugger_commands::mini_printf(std::ostream &stream, std::string_view forma m_console.printf("Not enough parameters for format!\n"); return false; } - if (u32(*param >> 32) != 0) - util::stream_format(stream, zerofill ? "%0*X" : "%*X", (width <= 8) ? 1 : width - 8, u32(*param >> 32)); - else if (width > 8) - util::stream_format(stream, zerofill ? "%0*X" : "%*X", width - 8, 0); - util::stream_format(stream, zerofill ? "%0*X" : "%*X", (width < 8) ? width : 8, u32(*param)); + util::stream_format(stream, zerofill ? "%0*X" : "%*X", width, *param); param++; params--; break; @@ -537,21 +536,7 @@ bool debugger_commands::mini_printf(std::ostream &stream, std::string_view forma m_console.printf("Not enough parameters for format!\n"); return false; } - if (u32(*param >> 60) != 0) - { - util::stream_format(stream, zerofill ? "%0*o" : "%*o", (width <= 20) ? 1 : width - 20, u32(*param >> 60)); - util::stream_format(stream, "%0*o", 10, u32(BIT(*param, 30, 30))); - } - else - { - if (width > 20) - util::stream_format(stream, zerofill ? "%0*o" : "%*o", width - 20, 0); - if (u32(BIT(*param, 30, 30)) != 0) - util::stream_format(stream, zerofill ? "%0*o" : "%*o", (width <= 10) ? 1 : width - 10, u32(BIT(*param, 30, 30))); - else if (width > 10) - util::stream_format(stream, zerofill ? "%0*o" : "%*o", width - 10, 0); - } - util::stream_format(stream, zerofill ? "%0*o" : "%*o", (width < 10) ? width : 10, u32(BIT(*param, 0, 30))); + util::stream_format(stream, zerofill ? "%0*o" : "%*o", width, *param); param++; params--; break; @@ -563,10 +548,23 @@ bool debugger_commands::mini_printf(std::ostream &stream, std::string_view forma m_console.printf("Not enough parameters for format!\n"); return false; } - util::stream_format(stream, zerofill ? "%0*d" : "%*d", width, u32(*param)); + util::stream_format(stream, zerofill ? "%0*d" : "%*d", width, s64(*param)); + param++; + params--; + break; + + case 'U': + case 'u': + if (params == 0) + { + m_console.printf("Not enough parameters for format!\n"); + return false; + } + util::stream_format(stream, zerofill ? "%0*u" : "%*u", width, *param); param++; params--; break; + case 'C': case 'c': if (params == 0) diff --git a/src/emu/debug/express.cpp b/src/emu/debug/express.cpp index f9074147b7b..ce4773d34c4 100644 --- a/src/emu/debug/express.cpp +++ b/src/emu/debug/express.cpp @@ -1953,14 +1953,14 @@ u64 parsed_expression::execute_tokens() pop_token_rval(t2); pop_token_rval(t1); if (t2.value() == 0) throw expression_error(expression_error::DIVIDE_BY_ZERO, t2.offset()); - push_token(result.configure_number(t1.value() / t2.value()).set_offset(t1, t2)); + push_token(result.configure_number(s64(t1.value()) / s64(t2.value())).set_offset(t1, t2)); break; case TVL_MODULO: pop_token_rval(t2); pop_token_rval(t1); if (t2.value() == 0) throw expression_error(expression_error::DIVIDE_BY_ZERO, t2.offset()); - push_token(result.configure_number(t1.value() % t2.value()).set_offset(t1, t2)); + push_token(result.configure_number(s64(t1.value()) % s64(t2.value())).set_offset(t1, t2)); break; case TVL_ADD: @@ -1980,27 +1980,27 @@ u64 parsed_expression::execute_tokens() case TVL_RSHIFT: pop_token_rval(t2); pop_token_rval(t1); - push_token(result.configure_number(t1.value() >> t2.value()).set_offset(t1, t2)); + push_token(result.configure_number(s64(t1.value()) >> t2.value()).set_offset(t1, t2)); break; case TVL_LESS: pop_token_rval(t2); pop_token_rval(t1); - push_token(result.configure_number(t1.value() < t2.value()).set_offset(t1, t2)); + push_token(result.configure_number(s64(t1.value()) < s64(t2.value())).set_offset(t1, t2)); break; case TVL_LESSOREQUAL: pop_token_rval(t2); pop_token_rval(t1); - push_token(result.configure_number(t1.value() <= t2.value()).set_offset(t1, t2)); + push_token(result.configure_number(s64(t1.value()) <= s64(t2.value())).set_offset(t1, t2)); break; case TVL_GREATER: pop_token_rval(t2); pop_token_rval(t1); - push_token(result.configure_number(t1.value() > t2.value()).set_offset(t1, t2)); + push_token(result.configure_number(s64(t1.value()) > s64(t2.value())).set_offset(t1, t2)); break; case TVL_GREATEROREQUAL: pop_token_rval(t2); pop_token_rval(t1); - push_token(result.configure_number(t1.value() >= t2.value()).set_offset(t1, t2)); + push_token(result.configure_number(s64(t1.value()) >= s64(t2.value())).set_offset(t1, t2)); break; case TVL_EQUAL: @@ -2054,7 +2054,7 @@ u64 parsed_expression::execute_tokens() pop_token_rval(t2); pop_token_lval(t1); if (t2.value() == 0) throw expression_error(expression_error::DIVIDE_BY_ZERO, t2.offset()); - push_token(result.configure_number(t1.get_lval_value(m_symtable) / t2.value()).set_offset(t1, t2)); + push_token(result.configure_number(s64(t1.get_lval_value(m_symtable)) / s64(t2.value())).set_offset(t1, t2)); t1.set_lval_value(m_symtable, result.value()); break; @@ -2062,7 +2062,7 @@ u64 parsed_expression::execute_tokens() pop_token_rval(t2); pop_token_lval(t1); if (t2.value() == 0) throw expression_error(expression_error::DIVIDE_BY_ZERO, t2.offset()); - push_token(result.configure_number(t1.get_lval_value(m_symtable) % t2.value()).set_offset(t1, t2)); + push_token(result.configure_number(s64(t1.get_lval_value(m_symtable)) % s64(t2.value())).set_offset(t1, t2)); t1.set_lval_value(m_symtable, result.value()); break; @@ -2086,7 +2086,7 @@ u64 parsed_expression::execute_tokens() case TVL_ASSIGNRSHIFT: pop_token_rval(t2); pop_token_lval(t1); - push_token(result.configure_number(t1.get_lval_value(m_symtable) >> t2.value()).set_offset(t1, t2)); + push_token(result.configure_number(s64(t1.get_lval_value(m_symtable)) >> t2.value()).set_offset(t1, t2)); t1.set_lval_value(m_symtable, result.value()); break; -- cgit v1.2.3