summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/sh
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2026-03-06 02:59:05 +1100
committer Vas Crabb <vas@vastheman.com>2026-03-06 02:59:05 +1100
commitfee23037375166275937e15caf0b45f5de1cb3c7 (patch)
tree9253e31804ecd5833999e7411ca38d9a3daa65be /src/devices/cpu/sh
parente2dbc608c38558ee078d675c08fc91e9726beee0 (diff)
More stuff mostly related to recompiling CPUs:
cpu/drcbearm64.cpp: Don't set the rounding mode on SETFMOD if it hasn't changed. cpu/e132xs.cpp: Skip more unnecessary flag calculations, use pre-calculated PC for updating G0 in memory when possible, better analysis of pre-calculated PC values when delay slots are involved. cpu/sh: Cleaned up register dependency analysis logging, fixed an instruction analysis bug. cpu/sharc: Disassemble unimplemented instructions executed in recompiled code, include tag in more fatal errors, use throw syntax to make it cleared it's an early out.
Diffstat (limited to 'src/devices/cpu/sh')
-rw-r--r--src/devices/cpu/sh/sh.cpp93
-rw-r--r--src/devices/cpu/sh/sh.h3
-rw-r--r--src/devices/cpu/sh/sh_fe.cpp60
-rw-r--r--src/devices/cpu/sh/sh_fe.h32
4 files changed, 94 insertions, 94 deletions
diff --git a/src/devices/cpu/sh/sh.cpp b/src/devices/cpu/sh/sh.cpp
index 72945b2e364..99a674fd91f 100644
--- a/src/devices/cpu/sh/sh.cpp
+++ b/src/devices/cpu/sh/sh.cpp
@@ -2033,75 +2033,6 @@ void sh_common_execution::save_fast_iregs(drcuml_block &block)
/*-------------------------------------------------
- log_register_list - log a list of GPR registers
--------------------------------------------------*/
-
-void sh_common_execution::log_register_list(const char *string, const std::bitset<32> &reglist, const std::bitset<32> *regnostarlist)
-{
- int count = 0;
-
- /* skip if nothing */
- if (reglist.none())
- return;
-
- m_drcuml->log_printf("[%s:", string);
-
- for (int regnum = 0; regnum < 16; regnum++)
- {
- if (reglist[opcode_desc::REG_R0 + regnum])
- {
- m_drcuml->log_printf("%sr%d", (count++ == 0) ? "" : ",", regnum);
- if (regnostarlist && !(*regnostarlist)[opcode_desc::REG_R0 + regnum])
- m_drcuml->log_printf("*");
- }
- }
-
- if (reglist[opcode_desc::REG_PR])
- {
- m_drcuml->log_printf("%spr", (count++ == 0) ? "" : ",");
- if (regnostarlist && !(*regnostarlist)[opcode_desc::REG_PR])
- m_drcuml->log_printf("*");
- }
-
- if (reglist[opcode_desc::REG_SR])
- {
- m_drcuml->log_printf("%ssr", (count++ == 0) ? "" : ",");
- if (regnostarlist && !(*regnostarlist)[opcode_desc::REG_SR])
- m_drcuml->log_printf("*");
- }
-
- if (reglist[opcode_desc::REG_MACL])
- {
- m_drcuml->log_printf("%smacl", (count++ == 0) ? "" : ",");
- if (regnostarlist && !(*regnostarlist)[opcode_desc::REG_MACL])
- m_drcuml->log_printf("*");
- }
-
- if (reglist[opcode_desc::REG_MACH])
- {
- m_drcuml->log_printf("%smach", (count++ == 0) ? "" : ",");
- if (regnostarlist && !(*regnostarlist)[opcode_desc::REG_MACH])
- m_drcuml->log_printf("*");
- }
-
- if (reglist[opcode_desc::REG_GBR])
- {
- m_drcuml->log_printf("%sgbr", (count++ == 0) ? "" : ",");
- if (regnostarlist && !(*regnostarlist)[opcode_desc::REG_GBR])
- m_drcuml->log_printf("*");
- }
-
- if (reglist[opcode_desc::REG_VBR])
- {
- m_drcuml->log_printf("%svbr", (count++ == 0) ? "" : ",");
- if (regnostarlist && !(*regnostarlist)[opcode_desc::REG_VBR])
- m_drcuml->log_printf("*");
- }
-
- m_drcuml->log_printf("] ");
-}
-
-/*-------------------------------------------------
log_opcode_desc - log a list of descriptions
-------------------------------------------------*/
@@ -2124,20 +2055,32 @@ void sh_common_execution::log_opcode_desc(const opcode_desc *desclist, int inden
buffer.put('\0');
m_drcuml->log_printf("%08X [%08X] t:%08X f:%s: ", desclist->pc, desclist->physpc, desclist->targetpc, &buffer.vec()[0]);
- /* disassemle the current instruction and output it to the log */
+ /* disassemble the current instruction and output it to the log */
buffer.clear();
buffer.seekp(0);
+ util::stream_format(buffer, "%*s", 4 * indent, "");
if (desclist->virtual_noop())
buffer << "<virtual nop>";
else
sh2d.dasm_one(buffer, desclist->pc, desclist->opptr);
buffer.put('\0');
- m_drcuml->log_printf("%-36s", &buffer.vec()[0]);
+ m_drcuml->log_printf(
+ (desclist->regin.any() || desclist->regout.any()) ? "%-36s" : "%s",
+ &buffer.vec()[0]);
- /* output register states */
- log_register_list("use", desclist->regin, nullptr);
- log_register_list("mod", desclist->regout, &desclist->regreq);
- m_drcuml->log_printf("\n");
+ /* output register dependencies */
+ buffer.clear();
+ buffer.seekp(0);
+ if (desclist->regin.any())
+ {
+ desclist->log_registers_used(buffer);
+ if (desclist->regout.any())
+ buffer << ' ';
+ }
+ if (desclist->regout.any())
+ desclist->log_registers_modified(buffer);
+ buffer.put('\0');
+ m_drcuml->log_printf("%s\n", &buffer.vec()[0]);
/* if we have a delay slot, output it recursively */
if (desclist->delay.first() != nullptr)
diff --git a/src/devices/cpu/sh/sh.h b/src/devices/cpu/sh/sh.h
index c06fbeddf10..fbf5e2a93f8 100644
--- a/src/devices/cpu/sh/sh.h
+++ b/src/devices/cpu/sh/sh.h
@@ -8,8 +8,6 @@
#include "cpu/drcuml.h"
-#include <bitset>
-
/***************************************************************************
DEBUGGING
@@ -443,7 +441,6 @@ public:
void alloc_handle(uml::code_handle *&handleptr, const char *name);
void load_fast_iregs(drcuml_block &block);
void save_fast_iregs(drcuml_block &block);
- void log_register_list(const char *string, const std::bitset<32> &reglist, const std::bitset<32> *regnostarlist);
void log_opcode_desc(const opcode_desc *desclist, int indent);
void log_add_disasm_comment(drcuml_block &block, uint32_t pc, uint32_t op);
void generate_delay_slot(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint32_t ovrpc);
diff --git a/src/devices/cpu/sh/sh_fe.cpp b/src/devices/cpu/sh/sh_fe.cpp
index 0716231aef7..a557109f7b7 100644
--- a/src/devices/cpu/sh/sh_fe.cpp
+++ b/src/devices/cpu/sh/sh_fe.cpp
@@ -63,6 +63,62 @@ void sh_common_execution::opcode_desc::log_flags(std::ostream &stream) const
}
+/*-------------------------------------------------
+ log_register_list - log a list of registers
+-------------------------------------------------*/
+
+void sh_common_execution::opcode_desc::log_registers_used(std::ostream &stream) const
+{
+ stream << "[use:";
+ log_register_list(stream, regin, nullptr);
+ stream << ']';
+}
+
+void sh_common_execution::opcode_desc::log_registers_modified(std::ostream &stream) const
+{
+ stream << "[mod:";
+ log_register_list(stream, regout, &regreq);
+ stream << ']';
+}
+
+void sh_common_execution::opcode_desc::log_register_list(std::ostream &stream, const regmask &reglist, const regmask *regnostarlist)
+{
+ int count = 0;
+
+ for (int regnum = 0; regnum < 16; regnum++)
+ {
+ if (reglist[REG_R0 + regnum])
+ {
+ if (count++)
+ stream << ',';
+ stream << 'r' << regnum;
+ if (regnostarlist && !(*regnostarlist)[REG_R0 + regnum])
+ stream << '*';
+ }
+ }
+
+ const auto log_bit =
+ [&stream, &count, &reglist, &regnostarlist] (size_t bit, const char *name)
+ {
+ if (reglist[bit])
+ {
+ if (count++)
+ stream << ',';
+ stream << name;
+ if (regnostarlist && !(*regnostarlist)[bit])
+ stream << '*';
+ }
+ };
+
+ log_bit(REG_PR, "pr");
+ log_bit(REG_SR, "sr");
+ log_bit(REG_MACL, "macl");
+ log_bit(REG_MACH, "mach");
+ log_bit(REG_GBR, "gbr");
+ log_bit(REG_VBR, "vbr");
+}
+
+
/***************************************************************************
INSTRUCTION PARSERS
@@ -313,7 +369,7 @@ bool sh_common_execution::frontend::describe_group_6(opcode_desc &desc, const op
case 5: // MOVWP(Rm, Rn);
case 6: // MOVLP(Rm, Rn);
desc.set_r_used(REG_M);
- desc.set_r_used(REG_N);
+ desc.set_r_modified(REG_M);
desc.set_r_modified(REG_N);
desc.set_reads_memory();
return true;
@@ -631,7 +687,7 @@ bool sh_common_execution::frontend::describe_group_0(opcode_desc &desc, const op
bool sh_common_execution::frontend::describe_group_4(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode)
{
- switch (opcode & 0x3F)
+ switch (opcode & 0x3f)
{
case 0x00: // SHLL(Rn);
case 0x01: // SHLR(Rn);
diff --git a/src/devices/cpu/sh/sh_fe.h b/src/devices/cpu/sh/sh_fe.h
index ba63138e3eb..266dc4f2821 100644
--- a/src/devices/cpu/sh/sh_fe.h
+++ b/src/devices/cpu/sh/sh_fe.h
@@ -23,20 +23,6 @@
class sh_common_execution::opcode_desc : public opcode_desc_base<opcode_desc, 32>
{
public:
- enum
- {
- REG_R0 = 0,
-
- REG_PR = REG_R0 + 16,
- REG_SR,
- REG_MACL,
- REG_MACH,
- REG_GBR,
- REG_VBR,
-
- REG_COUNT
- };
-
offs_t physpc; // physical PC of this opcode
uint16_t opptr; // copy of opcode
@@ -87,8 +73,26 @@ public:
}
void log_flags(std::ostream &stream) const;
+ void log_registers_used(std::ostream &stream) const;
+ void log_registers_modified(std::ostream &stream) const;
private:
+ enum
+ {
+ REG_R0 = 0,
+
+ REG_PR = REG_R0 + 16,
+ REG_SR,
+ REG_MACL,
+ REG_MACH,
+ REG_GBR,
+ REG_VBR,
+
+ REG_COUNT
+ };
+
+ static void log_register_list(std::ostream &stream, const regmask &reglist, const regmask *regnostarlist);
+
bool m_reads_memory;
bool m_writes_memory;
bool m_can_expose_external_int;