summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2026-03-07 03:20:05 +1100
committer Vas Crabb <vas@vastheman.com>2026-03-07 03:22:56 +1100
commit1f7fa43c3d2692d3523e8b72a24e04fff7c30a57 (patch)
tree404cc315d6e97ea55456270d3e2195b661a35a2a /src
parent0edf02aea873379876de8b42a8cfd00bd1967cc9 (diff)
cpu/sharc: Implemented a bit more functionality and fixed bugs:
* Implemented short word sign extension. * Fixed DAG2 (PM) register display in debugger. * Track AF dependencies when analysing instructions. * Log analysed instructions when logging UML code. * Removed misplaced break in cpu/sharc/sharcfe.cpp. * cpu/uml.h: Let C functions take any pointer/reference parameter.
Diffstat (limited to 'src')
-rw-r--r--src/devices/cpu/e132xs/e132xsdrc.cpp47
-rw-r--r--src/devices/cpu/e132xs/e1fe.cpp2
-rw-r--r--src/devices/cpu/powerpc/ppcfe.cpp2
-rw-r--r--src/devices/cpu/sh/sh_fe.cpp2
-rw-r--r--src/devices/cpu/sharc/sharc.cpp75
-rw-r--r--src/devices/cpu/sharc/sharc.h32
-rw-r--r--src/devices/cpu/sharc/sharcdrc.cpp375
-rw-r--r--src/devices/cpu/sharc/sharcfe.cpp221
-rw-r--r--src/devices/cpu/sharc/sharcfe.h63
-rw-r--r--src/devices/cpu/sharc/sharcops.hxx35
-rw-r--r--src/devices/cpu/uml.h9
11 files changed, 535 insertions, 328 deletions
diff --git a/src/devices/cpu/e132xs/e132xsdrc.cpp b/src/devices/cpu/e132xs/e132xsdrc.cpp
index b2b12bc1506..7195062c2d0 100644
--- a/src/devices/cpu/e132xs/e132xsdrc.cpp
+++ b/src/devices/cpu/e132xs/e132xsdrc.cpp
@@ -70,65 +70,60 @@ public:
struct hyperstone_device::c_funcs
{
- static void unimplemented(void *param)
+ static void unimplemented(hyperstone_device &that)
{
- auto &that = *reinterpret_cast<hyperstone_device *>(param);
fatalerror("PC=%08X: Unimplemented op %08X\n", that.PC, that.m_core->arg0);
}
- static void print(void *param)
+ static void print(hyperstone_device &that)
{
- auto &that = *reinterpret_cast<hyperstone_device *>(param);
printf("%c: %08x\n", (char)that.m_core->arg0, that.m_core->arg1);
}
- static void standard_irq_callback(void *param)
+ static void standard_irq_callback(hyperstone_device &that)
{
- auto &that = *reinterpret_cast<hyperstone_device *>(param);
that.standard_irq_callback(that.m_core->arg0, that.m_core->global_regs[0]);
}
- static void debugger_exception_hook(void *param)
+ static void debugger_exception_hook(hyperstone_device &that)
{
- auto &that = *reinterpret_cast<hyperstone_device *>(param);
that.debugger_exception_hook(int32_t(that.m_core->arg0));
}
- static void adjust_timer_interrupt(void *param)
+ static void adjust_timer_interrupt(hyperstone_device &that)
{
- reinterpret_cast<hyperstone_device *>(param)->adjust_timer_interrupt();
+ that.adjust_timer_interrupt();
}
- static void compute_tr(void *param)
+ static void compute_tr(hyperstone_device &that)
{
- reinterpret_cast<hyperstone_device *>(param)->compute_tr();
+ that.compute_tr();
}
- static void update_timer_prescale(void *param)
+ static void update_timer_prescale(hyperstone_device &that)
{
- reinterpret_cast<hyperstone_device *>(param)->update_timer_prescale();
+ that.update_timer_prescale();
}
- static void update_bus_control(void *param)
+ static void update_bus_control(hyperstone_device &that)
{
- reinterpret_cast<hyperstone_device *>(param)->update_bus_control();
+ that.update_bus_control();
}
- static void update_memory_control(void *param)
+ static void update_memory_control(hyperstone_device &that)
{
- reinterpret_cast<hyperstone_device *>(param)->update_memory_control();
+ that.update_memory_control();
}
#if E132XS_LOG_DRC_REGS || E132XS_LOG_INTERPRETER_REGS
- static void dump_registers(void *param)
+ static void dump_registers(hyperstone_device &that)
{
- reinterpret_cast<hyperstone_device *>(param)->dump_registers();
+ that.dump_registers();
}
#endif
- static void total_cycles(void *param)
+ static void total_cycles(hyperstone_device &that)
{
- auto &that = *reinterpret_cast<hyperstone_device *>(param);
that.m_core->numcycles = that.total_cycles();
}
};
@@ -268,8 +263,6 @@ void hyperstone_device::generate_get_trap_addr(drcuml_block &block, uml::code_la
void hyperstone_device::code_compile_block(uint8_t mode, offs_t pc)
{
compiler_state compiler(mode);
- const opcode_desc *seqhead, *seqlast;
- bool override = false;
auto profile = g_profiler.start(PROFILER_DRC_COMPILE);
@@ -278,6 +271,7 @@ void hyperstone_device::code_compile_block(uint8_t mode, offs_t pc)
if (m_drcuml->logging())
log_descriptions(desclist, 0);
+ bool override = false;
bool succeeded = false;
while (!succeeded)
{
@@ -287,14 +281,15 @@ void hyperstone_device::code_compile_block(uint8_t mode, offs_t pc)
drcuml_block &block(m_drcuml->begin_block(8192));
/* loop until we get through all instruction sequences */
- for (seqhead = desclist; seqhead != nullptr; seqhead = seqlast->next())
+ const opcode_desc *seqlast = nullptr;
+ for (const opcode_desc *seqhead = desclist; seqhead; seqhead = seqlast->next())
{
/* add a code log entry */
if (m_drcuml->logging())
block.append_comment("-------------------------");
/* determine the last instruction in this sequence */
- for (seqlast = seqhead; seqlast != nullptr; seqlast = seqlast->next())
+ for (seqlast = seqhead; seqlast; seqlast = seqlast->next())
if (seqlast->end_sequence())
break;
assert(seqlast != nullptr);
diff --git a/src/devices/cpu/e132xs/e1fe.cpp b/src/devices/cpu/e132xs/e1fe.cpp
index 7a397185317..56fbbc20286 100644
--- a/src/devices/cpu/e132xs/e1fe.cpp
+++ b/src/devices/cpu/e132xs/e1fe.cpp
@@ -15,6 +15,8 @@
#include "cpu/drcfe.ipp"
+#include <iostream>
+
void hyperstone_device::opcode_desc::log_flags(std::ostream &stream) const
diff --git a/src/devices/cpu/powerpc/ppcfe.cpp b/src/devices/cpu/powerpc/ppcfe.cpp
index e970e6706f8..991149578f8 100644
--- a/src/devices/cpu/powerpc/ppcfe.cpp
+++ b/src/devices/cpu/powerpc/ppcfe.cpp
@@ -15,6 +15,8 @@
#include "cpu/drcfe.ipp"
+#include <iostream>
+
/*-------------------------------------------------
diff --git a/src/devices/cpu/sh/sh_fe.cpp b/src/devices/cpu/sh/sh_fe.cpp
index a557109f7b7..6e888dedd3b 100644
--- a/src/devices/cpu/sh/sh_fe.cpp
+++ b/src/devices/cpu/sh/sh_fe.cpp
@@ -13,6 +13,8 @@
#include "cpu/drcfe.ipp"
+#include <iostream>
+
/*-------------------------------------------------
diff --git a/src/devices/cpu/sharc/sharc.cpp b/src/devices/cpu/sharc/sharc.cpp
index 0b11008ed99..5039686a7c7 100644
--- a/src/devices/cpu/sharc/sharc.cpp
+++ b/src/devices/cpu/sharc/sharc.cpp
@@ -97,8 +97,11 @@ void adsp21062_device::data_2m(address_map &map)
map(0x00000, 0x000ff).rw(FUNC(adsp21062_device::iop_r), FUNC(adsp21062_device::iop_w));
map(0x20000, 0x27fff).mirror(0x18000).ram().share(m_blocks[1]);
map(0x20000, 0x27fff).ram().share(m_blocks[0]);
- map(0x40000, 0x4ffff).mirror(0x30000).rw(FUNC(adsp21062_device::dmw_r<1>), FUNC(adsp21062_device::dmw_w<1>));
- map(0x40000, 0x4ffff).rw(FUNC(adsp21062_device::dmw_r<0>), FUNC(adsp21062_device::dmw_w<0>));
+ map(0x40000, 0x4ffff).mirror(0x30000).rw(FUNC(adsp21062_device::dm_short_r<1>), FUNC(adsp21062_device::dm_short_w<1>));
+ map(0x40000, 0x4ffff).rw(FUNC(adsp21062_device::dm_short_r<0>), FUNC(adsp21062_device::dm_short_w<0>));
+ map(0x40000, 0x7ffff).view(m_dm_short_view);
+ m_dm_short_view[0](0x40000, 0x4ffff).mirror(0x30000).r(FUNC(adsp21062_device::dm_short_se_r<1>));
+ m_dm_short_view[0](0x40000, 0x4ffff).r(FUNC(adsp21062_device::dm_short_se_r<0>));
}
void adsp21062_device::data_4m(address_map &map)
@@ -106,8 +109,11 @@ void adsp21062_device::data_4m(address_map &map)
map(0x00000, 0x000ff).rw(FUNC(adsp21062_device::iop_r), FUNC(adsp21062_device::iop_w));
map(0x20000, 0x2ffff).ram().share(m_blocks[0]);
map(0x30000, 0x3ffff).ram().share(m_blocks[1]);
- map(0x40000, 0x5ffff).rw(FUNC(adsp21062_device::dmw_r<0>), FUNC(adsp21062_device::dmw_w<0>));
- map(0x60000, 0x7ffff).rw(FUNC(adsp21062_device::dmw_r<1>), FUNC(adsp21062_device::dmw_w<1>));
+ map(0x40000, 0x5ffff).rw(FUNC(adsp21062_device::dm_short_r<0>), FUNC(adsp21062_device::dm_short_w<0>));
+ map(0x60000, 0x7ffff).rw(FUNC(adsp21062_device::dm_short_r<1>), FUNC(adsp21062_device::dm_short_w<1>));
+ map(0x40000, 0x7ffff).view(m_dm_short_view);
+ m_dm_short_view[0](0x40000, 0x5ffff).r(FUNC(adsp21062_device::dm_short_se_r<0>));
+ m_dm_short_view[0](0x60000, 0x7ffff).r(FUNC(adsp21062_device::dm_short_se_r<1>));
}
adsp21062_device::adsp21062_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
@@ -171,6 +177,7 @@ adsp21062_device::adsp21062_device(
, m_swap_dag2_4_7(nullptr)
, m_swap_r0_7(nullptr)
, m_swap_r8_15(nullptr)
+ , m_dm_short_view(*this, "short_words")
, m_flag_out_cb(*this)
, m_blocks(*this, "block%u", 0U)
, m_flag_pending_val{ 0, 0, 0, 0 }
@@ -327,13 +334,19 @@ void adsp21062_device::pm_w(offs_t offset, uint64_t data, uint64_t mem_mask)
}
template <unsigned N>
-uint32_t adsp21062_device::dmw_r(offs_t offset)
+uint32_t adsp21062_device::dm_short_r(offs_t offset)
{
return util::little_endian_cast<uint16_t const>(&m_blocks[N][0])[offset];
}
template <unsigned N>
-void adsp21062_device::dmw_w(offs_t offset, uint32_t data)
+uint32_t adsp21062_device::dm_short_se_r(offs_t offset)
+{
+ return uint32_t(int32_t(util::little_endian_cast<int16_t const>(&m_blocks[N][0])[offset]));
+}
+
+template <unsigned N>
+void adsp21062_device::dm_short_w(offs_t offset, uint32_t data)
{
util::little_endian_cast<uint16_t>(&m_blocks[N][0])[offset] = uint16_t(data);
}
@@ -850,21 +863,21 @@ void adsp21062_device::device_start()
save_item(NAME(m_core->astat_old_old));
save_item(NAME(m_core->astat_old_old_old));
- state_add( SHARC_PC, "PC", m_core->pc).mask(0x00ffffff).formatstr("%06X");
- state_add( SHARC_PCSTK, "PCSTK", m_core->pcstk).mask(0x00ffffff).formatstr("%06X");
- state_add( SHARC_PCSTKP, "PCSTKP", m_core->pcstkp).mask(0x1f).formatstr("%02X");
- state_add( SHARC_LSTKP, "LSTKP", m_core->lstkp).mask(0x07).formatstr("%01X");
- state_add( SHARC_FADDR, "FADDR", m_core->faddr).formatstr("%08X");
- state_add( SHARC_DADDR, "DADDR", m_core->daddr).formatstr("%08X");
- state_add( SHARC_MODE1, "MODE1", m_core->mode1).formatstr("%08X");
- state_add( SHARC_MODE2, "MODE2", m_core->mode2).formatstr("%08X");
- state_add( SHARC_ASTAT, "ASTAT", m_core->astat).formatstr("%08X").callimport().callexport();
- state_add( SHARC_IRPTL, "IRPTL", m_core->irptl).formatstr("%08X");
- state_add( SHARC_IMASK, "IMASK", m_core->imask).formatstr("%08X");
- state_add( SHARC_USTAT1, "USTAT1", m_core->ustat1).formatstr("%08X");
- state_add( SHARC_USTAT2, "USTAT2", m_core->ustat2).formatstr("%08X");
- state_add( SHARC_CURLCNTR, "CURLCNTR", m_core->curlcntr).formatstr("%08X");
- state_add( SHARC_STSTKP, "STSTKP", m_core->status_stkp).formatstr("%08X");
+ state_add(SHARC_PC, "PC", m_core->pc).mask(0x00ffffff).formatstr("%06X");
+ state_add(SHARC_PCSTK, "PCSTK", m_core->pcstk).mask(0x00ffffff).formatstr("%06X");
+ state_add(SHARC_PCSTKP, "PCSTKP", m_core->pcstkp).mask(0x1f).formatstr("%02X");
+ state_add(SHARC_LSTKP, "LSTKP", m_core->lstkp).mask(0x07).formatstr("%01X");
+ state_add(SHARC_FADDR, "FADDR", m_core->faddr).formatstr("%08X");
+ state_add(SHARC_DADDR, "DADDR", m_core->daddr).formatstr("%08X");
+ state_add(SHARC_MODE1, "MODE1", m_core->mode1).formatstr("%08X");
+ state_add(SHARC_MODE2, "MODE2", m_core->mode2).formatstr("%08X");
+ state_add(SHARC_ASTAT, "ASTAT", m_core->astat).formatstr("%08X").callimport().callexport();
+ state_add(SHARC_IRPTL, "IRPTL", m_core->irptl).formatstr("%08X");
+ state_add(SHARC_IMASK, "IMASK", m_core->imask).formatstr("%08X");
+ state_add(SHARC_USTAT1, "USTAT1", m_core->ustat1).formatstr("%08X");
+ state_add(SHARC_USTAT2, "USTAT2", m_core->ustat2).formatstr("%08X");
+ state_add(SHARC_CURLCNTR, "CURLCNTR", m_core->curlcntr).formatstr("%08X");
+ state_add(SHARC_STSTKP, "STSTKP", m_core->status_stkp).formatstr("%08X");
char namebuf[8];
for (int i = 0; 16 > i; ++i)
@@ -876,29 +889,37 @@ void adsp21062_device::device_start()
{
std::snprintf(namebuf, std::size(namebuf), "I%d", i);
auto &dag((i < 8) ? m_core->dag1 : m_core->dag2);
- state_add(SHARC_I0 + i, namebuf, dag.i[i]).formatstr("%08X");
+ auto const mask((i < 8) ? 0xffffffff : 0x00ffffff);
+ auto const format((i < 8) ? "%08X" : "%06X");
+ state_add(SHARC_I0 + i, namebuf, dag.i[i & 0x7]).mask(mask).formatstr(format);
}
for (int i = 0; 16 > i; ++i)
{
std::snprintf(namebuf, std::size(namebuf), "M%d", i);
auto &dag((i < 8) ? m_core->dag1 : m_core->dag2);
- state_add(SHARC_M0 + i, namebuf, dag.m[i]).formatstr("%08X");
+ auto const mask((i < 8) ? 0xffffffff : 0x00ffffff);
+ auto const format((i < 8) ? "%08X" : "%06X");
+ state_add(SHARC_M0 + i, namebuf, dag.m[i & 0x7]).mask(mask).formatstr(format);
}
for (int i = 0; 16 > i; ++i)
{
std::snprintf(namebuf, std::size(namebuf), "L%d", i);
auto &dag((i < 8) ? m_core->dag1 : m_core->dag2);
- state_add(SHARC_L0 + i, namebuf, dag.l[i]).formatstr("%08X");
+ auto const mask((i < 8) ? 0xffffffff : 0x00ffffff);
+ auto const format((i < 8) ? "%08X" : "%06X");
+ state_add(SHARC_L0 + i, namebuf, dag.l[i & 0x7]).mask(mask).formatstr(format);
}
for (int i = 0; 16 > i; ++i)
{
std::snprintf(namebuf, std::size(namebuf), "B%d", i);
auto &dag((i < 8) ? m_core->dag1 : m_core->dag2);
- state_add(SHARC_B0 + i, namebuf, dag.b[i]).formatstr("%08X");
+ auto const mask((i < 8) ? 0xffffffff : 0x00ffffff);
+ auto const format((i < 8) ? "%08X" : "%06X");
+ state_add(SHARC_B0 + i, namebuf, dag.b[i & 0x7]).mask(mask).formatstr(format);
}
- state_add( STATE_GENPC, "GENPC", m_core->pc).noshow();
- state_add( STATE_GENPCBASE, "CURPC", m_core->pc).noshow();
+ state_add(STATE_GENPC, "GENPC", m_core->pc).noshow();
+ state_add(STATE_GENPCBASE, "CURPC", m_core->pc).noshow();
set_icountptr(m_core->icount);
}
diff --git a/src/devices/cpu/sharc/sharc.h b/src/devices/cpu/sharc/sharc.h
index 95b712eff84..45f3f8796e5 100644
--- a/src/devices/cpu/sharc/sharc.h
+++ b/src/devices/cpu/sharc/sharc.h
@@ -8,6 +8,9 @@
#include "cpu/drcuml.h"
+class sharc_disassembler;
+
+
class adsp21062_device : public cpu_device
{
public:
@@ -38,8 +41,9 @@ public:
template <unsigned N> uint64_t pm_r(offs_t offset);
template <unsigned N> void pm_w(offs_t offset, uint64_t data, uint64_t mem_mask = ~0);
- template <unsigned N> uint32_t dmw_r(offs_t offset);
- template <unsigned N> void dmw_w(offs_t offset, uint32_t data);
+ template <unsigned N> uint32_t dm_short_r(offs_t offset);
+ template <unsigned N> uint32_t dm_short_se_r(offs_t offset);
+ template <unsigned N> void dm_short_w(offs_t offset, uint32_t data);
uint32_t iop_r(offs_t offset);
void iop_w(offs_t offset, uint32_t data);
@@ -130,7 +134,7 @@ private:
static constexpr uint32_t MV = 0x0000'0080; // Multiplier overflow
static constexpr uint32_t MU = 0x0000'0100; // Multiplier underflow
static constexpr uint32_t MI = 0x0000'0200; // Multiplier floating-point invalid operation
- static constexpr uint32_t AF = 0x0000'0400;
+ static constexpr uint32_t AF = 0x0000'0400; // Last ALU operation was a floating-point operation
static constexpr uint32_t SV = 0x0000'0800; // Shifter overflow
static constexpr uint32_t SZ = 0x0000'1000; // Shifter result zero
static constexpr uint32_t SS = 0x0000'2000; // Shifter input sign
@@ -188,6 +192,8 @@ private:
static constexpr uint32_t MODE2_CAFRZ = 0x0008'0000; // Cache freeze
+ struct cfuncs;
+
using opcode_func = void (adsp21062_device::*)();
struct SHARC_OP
{
@@ -283,6 +289,7 @@ private:
uml::code_handle *m_swap_r0_7;
uml::code_handle *m_swap_r8_15;
+ memory_view m_dm_short_view;
memory_access<24, 3, -3, ENDIANNESS_LITTLE>::specific m_program;
memory_access<32, 2, -2, ENDIANNESS_LITTLE>::specific m_data;
@@ -300,8 +307,8 @@ private:
bool m_input_update_pending;
bool m_enable_drc;
- static std::string disassemble_one(uint32_t pc, uint64_t opcode);
- void build_opcode_table();
+ static std::string disassemble_one(uint32_t pc, uint64_t opcode) ATTR_COLD;
+ void build_opcode_table() ATTR_COLD;
TIMER_CALLBACK_MEMBER(sharc_iop_delayed_write_callback);
TIMER_CALLBACK_MEMBER(sharc_dma_callback);
@@ -380,7 +387,7 @@ private:
void sharcop_push_pop_stacks();
void sharcop_nop();
void sharcop_idle();
- void sharcop_unimplemented();
+ [[noreturn]] void sharcop_unimplemented() ATTR_COLD;
inline void compute_add(int rn, int rx, int ry);
inline void compute_sub(int rn, int rx, int ry);
inline void compute_add_ci(int rn, int rx, int ry);
@@ -454,6 +461,7 @@ private:
};
void execute_run_drc();
+ void log_descriptions(const sharc_disassembler &disassembler, const opcode_desc *desc_list, unsigned indent);
void generate_invariant();
void flush_drc_cache();
void compile_block(offs_t pc);
@@ -496,18 +504,6 @@ private:
bool if_condition_always_true(int condition);
uint32_t do_condition_astat_bits(int condition);
-
- template <unsigned N> static void cfunc_update_flag_out(void *param);
-
- [[noreturn]] static void cfunc_unimplemented(void *param) ATTR_COLD;
- [[noreturn]] static void cfunc_unimplemented_compute(void *param) ATTR_COLD;
- [[noreturn]] static void cfunc_unimplemented_shiftimm(void *param) ATTR_COLD;
- [[noreturn]] static void cfunc_pcstack_overflow(void *param) ATTR_COLD;
- [[noreturn]] static void cfunc_pcstack_underflow(void *param) ATTR_COLD;
- [[noreturn]] static void cfunc_loopstack_overflow(void *param) ATTR_COLD;
- [[noreturn]] static void cfunc_loopstack_underflow(void *param) ATTR_COLD;
- [[noreturn]] static void cfunc_statusstack_overflow(void *param) ATTR_COLD;
- [[noreturn]] static void cfunc_statusstack_underflow(void *param) ATTR_COLD;
};
diff --git a/src/devices/cpu/sharc/sharcdrc.cpp b/src/devices/cpu/sharc/sharcdrc.cpp
index d4b288458af..074bcb9048f 100644
--- a/src/devices/cpu/sharc/sharcdrc.cpp
+++ b/src/devices/cpu/sharc/sharcdrc.cpp
@@ -10,12 +10,17 @@
#include "emu.h"
#include "sharc.h"
+#include "sharc_dasm.h"
#include "sharcfe.h"
#include "sharcinternal.ipp"
#include "cpu/drcuml.h"
#include "cpu/drcumlsh.h"
+#include "util/vecstream.h"
+
+#include <locale>
+
#define USE_ASTAT_ELISION 1
#define USE_FAST_APPROX 0
@@ -117,81 +122,82 @@ const uint32_t loop_cond_map[16] = {
} // anonymous namespace
-inline void adsp21062_device::alloc_handle(uml::code_handle *&handleptr, const char *name)
+
+
+struct adsp21062_device::cfuncs
{
- if (!handleptr)
- handleptr = m_drcuml->handle_alloc(name);
-}
+ static void update_sse(adsp21062_device &sharc)
+ {
+ if (sharc.m_core->mode1 & MODE1_SSE)
+ sharc.m_dm_short_view.select(0);
+ else
+ sharc.m_dm_short_view.disable();
+ }
+ template <unsigned N>
+ static void update_flag_out(adsp21062_device &sharc)
+ {
+ sharc.m_flag_out_cb[N](BIT(sharc.m_core->astat, FLG0_SHIFT + N));
+ }
-template <unsigned N>
-void adsp21062_device::cfunc_update_flag_out(void *param)
-{
- auto &sharc = *reinterpret_cast<adsp21062_device *>(param);
- sharc.m_flag_out_cb[N](BIT(sharc.m_core->astat, FLG0_SHIFT + N));
-}
+ [[noreturn]] static void unimplemented(adsp21062_device &sharc) ATTR_COLD
+ {
+ throw emu_fatalerror("%s: PC=%08X: Unimplemented op %012X: %s",
+ sharc.tag(), sharc.m_core->pc, sharc.m_core->arg64, disassemble_one(sharc.m_core->pc, sharc.m_core->arg64));
+ }
+ [[noreturn]] static void unimplemented_compute(adsp21062_device &sharc) ATTR_COLD
+ {
+ throw emu_fatalerror("%s: PC=%08X: Unimplemented compute %012X: %s",
+ sharc.tag(), sharc.m_core->pc, sharc.m_core->arg64, disassemble_one(sharc.m_core->pc, sharc.m_core->arg64));
+ }
-void adsp21062_device::cfunc_unimplemented(void *param)
-{
- auto &sharc = *reinterpret_cast<adsp21062_device *>(param);
- throw emu_fatalerror("%s: PC=%08X: Unimplemented op %012X: %s",
- sharc.tag(), sharc.m_core->pc, sharc.m_core->arg64, disassemble_one(sharc.m_core->pc, sharc.m_core->arg64));
-}
+ [[noreturn]] static void unimplemented_shiftimm(adsp21062_device &sharc) ATTR_COLD
+ {
+ throw emu_fatalerror("%s: PC=%08X: Unimplemented shiftimm %012X: %s",
+ sharc.tag(), sharc.m_core->pc, sharc.m_core->arg64, disassemble_one(sharc.m_core->pc, sharc.m_core->arg64));
+ }
-void adsp21062_device::cfunc_unimplemented_compute(void *param)
-{
- auto &sharc = *reinterpret_cast<adsp21062_device *>(param);
- throw emu_fatalerror("%s: PC=%08X: Unimplemented compute %012X: %s",
- sharc.tag(), sharc.m_core->pc, sharc.m_core->arg64, disassemble_one(sharc.m_core->pc, sharc.m_core->arg64));
-}
+ [[noreturn]] static void pcstack_overflow(adsp21062_device &sharc) ATTR_COLD
+ {
+ throw emu_fatalerror("%s: PC=%08X: PCStack overflow", sharc.tag(), sharc.m_core->pc);
+ }
-void adsp21062_device::cfunc_unimplemented_shiftimm(void *param)
-{
- auto &sharc = *reinterpret_cast<adsp21062_device *>(param);
- throw emu_fatalerror("%s: PC=%08X: Unimplemented shiftimm %012X: %s",
- sharc.tag(), sharc.m_core->pc, sharc.m_core->arg64, disassemble_one(sharc.m_core->pc, sharc.m_core->arg64));
-}
+ [[noreturn]] static void pcstack_underflow(adsp21062_device &sharc) ATTR_COLD
+ {
+ throw emu_fatalerror("%s: PC=%08X: PCStack underflow", sharc.tag(), sharc.m_core->pc);
+ }
-void adsp21062_device::cfunc_pcstack_overflow(void *param)
-{
- auto &sharc = *reinterpret_cast<adsp21062_device *>(param);
- throw emu_fatalerror("%s: PC=%08X: PCStack overflow", sharc.tag(), sharc.m_core->pc);
-}
+ [[noreturn]] static void loopstack_overflow(adsp21062_device &sharc) ATTR_COLD
+ {
+ throw emu_fatalerror("%s: PC=%08X: Loop Stack overflow", sharc.tag(), sharc.m_core->pc);
+ }
-void adsp21062_device::cfunc_pcstack_underflow(void *param)
-{
- auto &sharc = *reinterpret_cast<adsp21062_device *>(param);
- throw emu_fatalerror("%s: PC=%08X: PCStack underflow", sharc.tag(), sharc.m_core->pc);
-}
+ [[noreturn]] static void loopstack_underflow(adsp21062_device &sharc) ATTR_COLD
+ {
+ throw emu_fatalerror("%s: PC=%08X: Loop Stack underflow", sharc.tag(), sharc.m_core->pc);
+ }
-void adsp21062_device::cfunc_loopstack_overflow(void *param)
-{
- auto &sharc = *reinterpret_cast<adsp21062_device *>(param);
- throw emu_fatalerror("%s: PC=%08X: Loop Stack overflow", sharc.tag(), sharc.m_core->pc);
-}
+ [[noreturn]] static void statusstack_overflow(adsp21062_device &sharc) ATTR_COLD
+ {
+ throw emu_fatalerror("%s: PC=%08X: Status Stack overflow", sharc.tag(), sharc.m_core->pc);
+ }
-void adsp21062_device::cfunc_loopstack_underflow(void *param)
-{
- auto &sharc = *reinterpret_cast<adsp21062_device *>(param);
- throw emu_fatalerror("%s: PC=%08X: Loop Stack underflow", sharc.tag(), sharc.m_core->pc);
-}
+ [[noreturn]] static void statusstack_underflow(adsp21062_device &sharc) ATTR_COLD
+ {
+ throw emu_fatalerror("%s: PC=%08X: Status Stack underflow", sharc.tag(), sharc.m_core->pc);
+ }
+};
-void adsp21062_device::cfunc_statusstack_overflow(void *param)
-{
- auto &sharc = *reinterpret_cast<adsp21062_device *>(param);
- throw emu_fatalerror("%s: PC=%08X: Status Stack overflow", sharc.tag(), sharc.m_core->pc);
-}
-void adsp21062_device::cfunc_statusstack_underflow(void *param)
+inline void adsp21062_device::alloc_handle(uml::code_handle *&handleptr, const char *name)
{
- auto &sharc = *reinterpret_cast<adsp21062_device *>(param);
- throw emu_fatalerror("%s: PC=%08X: Status Stack underflow", sharc.tag(), sharc.m_core->pc);
+ if (!handleptr)
+ handleptr = m_drcuml->handle_alloc(name);
}
-
bool adsp21062_device::if_condition_always_true(int condition)
{
if (condition == 0x1f || condition == 0x1e)
@@ -205,26 +211,26 @@ uint32_t adsp21062_device::do_condition_astat_bits(int condition)
uint32_t r = 0;
switch (condition)
{
- case 0x00: r = AZ; break; // EQ
- case 0x01: r = AZ | AN; break; // LT
- case 0x02: r = AZ | AN; break; // LE
- case 0x03: r = AC; break; // AC
- case 0x04: r = AV; break; // AV
- case 0x05: r = MV; break; // MV
- case 0x06: r = MN; break; // MS
- case 0x07: r = SV; break; // SV
- case 0x08: r = SZ; break; // SZ
- case 0x0d: r = BTF; break; // TF
- case 0x10: r = AZ; break; // NOT EQUAL
- case 0x11: r = AZ | AN; break; // GE
- case 0x12: r = AZ | AN; break; // GT
- case 0x13: r = AC; break; // NOT AC
- case 0x14: r = AV; break; // NOT AV
- case 0x15: r = MV; break; // NOT MV
- case 0x16: r = MN; break; // NOT MS
- case 0x17: r = SV; break; // NOT SV
- case 0x18: r = SZ; break; // NOT SZ
- case 0x1d: r = BTF; break; // NOT TF
+ case 0x00: r = AZ; break; // EQ
+ case 0x01: r = AZ | AV | AN | AF; break; // LT
+ case 0x02: r = AZ | AV | AN | AF; break; // LE
+ case 0x03: r = AC; break; // AC
+ case 0x04: r = AV; break; // AV
+ case 0x05: r = MV; break; // MV
+ case 0x06: r = MN; break; // MS
+ case 0x07: r = SV; break; // SV
+ case 0x08: r = SZ; break; // SZ
+ case 0x0d: r = BTF; break; // TF
+ case 0x10: r = AZ; break; // NOT EQUAL
+ case 0x11: r = AZ | AV | AN | AF; break; // GE
+ case 0x12: r = AZ | AV | AN | AF; break; // GT
+ case 0x13: r = AC; break; // NOT AC
+ case 0x14: r = AV; break; // NOT AV
+ case 0x15: r = MV; break; // NOT MV
+ case 0x16: r = MN; break; // NOT MS
+ case 0x17: r = SV; break; // NOT SV
+ case 0x18: r = SZ; break; // NOT SZ
+ case 0x1d: r = BTF; break; // NOT TF
}
return r;
@@ -323,6 +329,7 @@ void adsp21062_device::static_generate_memory_accessors()
uml::code_label const space_access = label++;
uml::code_label const sram_short = label++;
uml::code_label const sram_short_block1 = label++;
+ uml::code_label const sram_short_sext = label++;
UML_HANDLE(block, *m_dm_read32);
UML_CMP(block, I1, 0x20000);
@@ -351,10 +358,16 @@ void adsp21062_device::static_generate_memory_accessors()
UML_JMPc(block, COND_NZ, sram_short_block1);
UML_AND(block, I1, I1, (m_blocks[0].length() << 1) - 1);
UML_LOAD(block, I0, &m_blocks[0][0], I1, SIZE_WORD, SCALE_x2);
+ UML_TEST(block, MODE1, MODE1_SSE);
+ UML_JMPc(block, COND_NZ, sram_short_sext);
UML_RET(block);
UML_LABEL(block, sram_short_block1);
UML_AND(block, I1, I1, (m_blocks[0].length() << 1) - 1);
UML_LOAD(block, I0, &m_blocks[1][0], I1, SIZE_WORD, SCALE_x2);
+ UML_TEST(block, MODE1, MODE1_SSE);
+ UML_RETc(block, COND_Z);
+ UML_LABEL(block, sram_short_sext);
+ UML_SEXT(block, I0, I0, SIZE_WORD);
UML_RET(block);
}
@@ -426,7 +439,7 @@ void adsp21062_device::static_generate_push_pc()
UML_MOV(block, I1, PCSTKP);
UML_CMP(block, I1, 30);
UML_JMPc(block, COND_B, no_overflow);
- UML_CALLC(block, cfunc_pcstack_overflow, this);
+ UML_CALLC(block, cfuncs::pcstack_overflow, this);
UML_LABEL(block, no_overflow);
// store the top-of-stack pseudo-register if the stack isn't empty
@@ -469,7 +482,7 @@ void adsp21062_device::static_generate_pop_pc()
UML_SUB(block, I1, PCSTKP, 1);
UML_MOV(block, I0, PCSTK);
UML_JMPc(block, COND_AE, no_underflow);
- UML_CALLC(block, cfunc_pcstack_underflow, this);
+ UML_CALLC(block, cfuncs::pcstack_underflow, this);
UML_LABEL(block, no_underflow);
UML_MOV(block, PCSTKP, I1);
@@ -507,7 +520,7 @@ void adsp21062_device::static_generate_push_loop()
UML_MOV(block, I1, LSTKP);
UML_CMP(block, I1, 6);
UML_JMPc(block, COND_B, no_overflow);
- UML_CALLC(block, cfunc_loopstack_overflow, this);
+ UML_CALLC(block, cfuncs::loopstack_overflow, this);
UML_LABEL(block, no_overflow);
// store the top-of-stack pseudo-registers if the stack isn't empty
@@ -556,7 +569,7 @@ void adsp21062_device::static_generate_pop_loop()
// check for stack underflow
UML_SUB(block, I0, LSTKP, 1);
UML_JMPc(block, COND_NS, no_underflow);
- UML_CALLC(block, cfunc_loopstack_underflow, this);
+ UML_CALLC(block, cfuncs::loopstack_underflow, this);
UML_LABEL(block, no_underflow);
UML_MOV(block, LSTKP, I0);
@@ -600,7 +613,7 @@ void adsp21062_device::static_generate_push_status()
UML_ADD(block, I2, mem(&m_core->status_stkp), 1);
UML_CMP(block, I2, 5);
UML_JMPc(block, COND_B, no_overflow);
- UML_CALLC(block, cfunc_statusstack_overflow, this);
+ UML_CALLC(block, cfuncs::statusstack_overflow, this);
UML_LABEL(block, no_overflow);
UML_MOV(block, mem(&m_core->status_stkp), I2);
UML_AND(block, STKY, STKY, ~SSEM);
@@ -645,7 +658,7 @@ void adsp21062_device::static_generate_pop_status()
UML_SUB(block, I2, mem(&m_core->status_stkp), 1);
UML_JMPc(block, COND_NS, no_underflow);
- UML_CALLC(block, cfunc_statusstack_underflow, this);
+ UML_CALLC(block, cfuncs::statusstack_underflow, this);
UML_LABEL(block, no_underflow);
UML_MOV(block, mem(&m_core->status_stkp), I2);
UML_JMPc(block, COND_NZ, do_load);
@@ -675,29 +688,34 @@ void adsp21062_device::static_generate_pop_status()
UML_MOV(block, MODE1, I0);
// DAG1 regs 4-7
- UML_TEST(block, I2, 0x8); // don't swap if the bits are same
+ UML_TEST(block, I2, MODE1_SRD1H); // don't swap if the bits are same
UML_CALLHc(block, COND_NZ, *m_swap_dag1_4_7);
// DAG1 regs 0-3
- UML_TEST(block, I2, 0x10); // don't swap if the bits are same
+ UML_TEST(block, I2, MODE1_SRD1L); // don't swap if the bits are same
UML_CALLHc(block, COND_NZ, *m_swap_dag1_0_3);
// DAG2 regs 4-7
- UML_TEST(block, I2, 0x20); // don't swap if the bits are same
+ UML_TEST(block, I2, MODE1_SRD2H); // don't swap if the bits are same
UML_CALLHc(block, COND_NZ, *m_swap_dag2_4_7);
// DAG2 regs 0-3
- UML_TEST(block, I2, 0x40); // don't swap if the bits are same
+ UML_TEST(block, I2, MODE1_SRD2L); // don't swap if the bits are same
UML_CALLHc(block, COND_NZ, *m_swap_dag2_0_3);
// REG 8-15
- UML_TEST(block, I2, 0x80); // don't swap if the bits are same
+ UML_TEST(block, I2, MODE1_SRRFH); // don't swap if the bits are same
UML_CALLHc(block, COND_NZ, *m_swap_r8_15);
// REG 0-7
- UML_TEST(block, I2, 0x400); // don't swap if the bits are same
+ UML_TEST(block, I2, MODE1_SRRFL); // don't swap if the bits are same
UML_CALLHc(block, COND_NZ, *m_swap_r0_7);
+ // short word sign extension
+ UML_TEST(block, I2, MODE1_SSE); // don't update if the bits are the same
+ UML_RETc(block, COND_Z);
+ UML_CALLC(block, cfuncs::update_sse, this);
+
UML_RET(block);
block.end();
@@ -1147,10 +1165,14 @@ void adsp21062_device::compile_block(offs_t pc)
{
compiler_state compiler;
- bool override = false;
-
- const opcode_desc *const desclist = m_drcfe->describe_code(pc);
+ opcode_desc const *const desclist = m_drcfe->describe_code(pc);
+ if (m_drcuml->logging())
+ {
+ sharc_disassembler const disassembler;
+ log_descriptions(disassembler, desclist, 0);
+ }
+ bool override = false;
bool succeeded = false;
while (!succeeded)
{
@@ -1161,6 +1183,10 @@ void adsp21062_device::compile_block(offs_t pc)
const opcode_desc *seqlast = nullptr;
for (const opcode_desc *seqhead = desclist; seqhead; seqhead = seqlast->next())
{
+ // add a code log entry
+ if (m_drcuml->logging())
+ block.append_comment("-------------------------");
+
// determine the last instruction in this sequence
seqlast = seqhead;
while (seqlast && !seqlast->end_sequence())
@@ -1230,6 +1256,62 @@ void adsp21062_device::compile_block(offs_t pc)
}
+void adsp21062_device::log_descriptions(const sharc_disassembler &disassembler, const opcode_desc *desc_list, unsigned indent)
+{
+ util::ovectorstream buffer;
+ buffer.imbue(std::locale::classic());
+
+ // assume no indent is the start of a sequence and needs a heading
+ if (!indent)
+ m_drcuml->log_printf("\nDescriptor list @ %08X\n", desc_list->pc);
+
+ for ( ; desc_list; desc_list = desc_list->next())
+ {
+ buffer.clear();
+ buffer.seekp(0);
+ desc_list->log_flags(buffer);
+ buffer.put('\0');
+
+ m_drcuml->log_printf("%08X t:%08X f:%s: ", desc_list->pc, desc_list->targetpc, &buffer.vec()[0]);
+
+ // disassemble the current instruction and output it to the log
+ buffer.clear();
+ buffer.seekp(0);
+ util::stream_format(buffer, "%*s", 4 * indent, "");
+ if (desc_list->virtual_noop())
+ buffer << "<virtual nop>";
+ else
+ disassembler.disassemble_one(buffer, desc_list->pc, desc_list->opptr);
+ buffer.put('\0');
+ m_drcuml->log_printf(
+ (desc_list->regin.any() || desc_list->regout.any()) ? "%-48s" : "%s",
+ &buffer.vec()[0]);
+
+ // output register dependencies
+ buffer.clear();
+ buffer.seekp(0);
+ if (desc_list->regin.any())
+ {
+ desc_list->log_registers_used(buffer);
+ if (desc_list->regout.any())
+ buffer << ' ';
+ }
+ if (desc_list->regout.any())
+ desc_list->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 (desc_list->delay.first())
+ log_descriptions(disassembler, desc_list->delay.first(), indent + 1);
+
+ // at the end of a sequence add a dividing line
+ if (desc_list->end_sequence())
+ m_drcuml->log_printf("-----\n");
+ }
+}
+
+
void adsp21062_device::generate_invariant()
{
try
@@ -1359,20 +1441,20 @@ void adsp21062_device::generate_sequence_instruction(drcuml_block &block, compil
// log_add_disasm_comment(block, desc->pc, desc->opptr);
/* set the PC map variable */
- UML_MAPVAR(block, MAPVAR_PC, desc->pc); // mapvar PC,desc->pc
+ UML_MAPVAR(block, MAPVAR_PC, desc->pc);
/* accumulate total cycles */
compiler.cycles += 1;
/* update the icount map variable */
- UML_MAPVAR(block, MAPVAR_CYCLES, compiler.cycles); // mapvar CYCLES,compiler.cycles
+ UML_MAPVAR(block, MAPVAR_CYCLES, compiler.cycles);
/* if we are debugging, call the debugger */
if (debugger_enabled())
{
- UML_MOV(block, mem(&m_core->pc), desc->pc); // mov [pc],desc->pc
- save_fast_iregs(block); // <save fastregs>
- UML_DEBUG(block, desc->pc); // debug desc->pc
+ UML_MOV(block, mem(&m_core->pc), desc->pc);
+ save_fast_iregs(block);
+ UML_DEBUG(block, desc->pc);
}
// handle a special case where call is used as the last operation in a loop
@@ -1384,7 +1466,7 @@ void adsp21062_device::generate_sequence_instruction(drcuml_block &block, compil
/* if this is an invalid opcode, generate the exception now */
// if (desc->invalid_opcode())
-// UML_EXH(block, *m_exception[EXCEPTION_PROGRAM], 0x80000); // exh exception_program,0x80000
+// UML_EXH(block, *m_exception[EXCEPTION_PROGRAM], 0x80000);
/* unless this is a virtual no-op, it's a regular instruction */
if (!desc->virtual_noop())
@@ -1392,9 +1474,9 @@ void adsp21062_device::generate_sequence_instruction(drcuml_block &block, compil
/* compile the instruction */
if (!generate_opcode(block, compiler, desc))
{
- UML_MOV(block, mem(&m_core->pc), desc->pc); // mov [pc],desc->pc
- UML_DMOV(block, mem(&m_core->arg64), desc->opptr); // dmov [arg64],*desc->opptr
- UML_CALLC(block, cfunc_unimplemented, this); // callc cfunc_unimplemented,ppc
+ UML_MOV(block, mem(&m_core->pc), desc->pc);
+ UML_DMOV(block, mem(&m_core->arg64), desc->opptr);
+ UML_CALLC(block, cfuncs::unimplemented, this);
}
}
@@ -1498,38 +1580,47 @@ void adsp21062_device::generate_update_cycles(drcuml_block &block, compiler_stat
void adsp21062_device::generate_write_mode1_imm(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint32_t data)
{
// TODO: swap effects
- if (data & 0x1)
+ if (data & MODE1_BR8)
fatalerror("generate_write_mode1_imm: tried to enable I8 bit reversing");
- if (data & 0x2)
+ if (data & MODE1_BR0)
fatalerror("generate_write_mode1_imm: tried to enable I0 bit reversing");
- if (data & 0x4)
+ if (data & MODE1_SRCU)
fatalerror("generate_write_mode1_imm: tried to enable MR alternate");
+ uml::code_label const skip_sse = compiler.labelnum++;
+
+ UML_MOV(block, I2, MODE1);
+ UML_MOV(block, MODE1, data);
+
// DAG1 regs 4-7
- UML_TEST(block, MODE1, 0x8); // don't swap if the bits are same
- UML_CALLHc(block, (data & 0x8) ? COND_Z : COND_NZ, *m_swap_dag1_4_7);
+ UML_TEST(block, I2, MODE1_SRD1H); // don't swap if the bits are same
+ UML_CALLHc(block, (data & MODE1_SRD1H) ? COND_Z : COND_NZ, *m_swap_dag1_4_7);
// DAG1 regs 0-3
- UML_TEST(block, MODE1, 0x10); // don't swap if the bits are same
- UML_CALLHc(block, (data & 0x10) ? COND_Z : COND_NZ, *m_swap_dag1_0_3);
+ UML_TEST(block, I2, MODE1_SRD1L); // don't swap if the bits are same
+ UML_CALLHc(block, (data & MODE1_SRD1L) ? COND_Z : COND_NZ, *m_swap_dag1_0_3);
// DAG2 regs 4-7
- UML_TEST(block, MODE1, 0x20); // don't swap if the bits are same
- UML_CALLHc(block, (data & 0x20) ? COND_Z : COND_NZ, *m_swap_dag2_4_7);
+ UML_TEST(block, I2, MODE1_SRD2H); // don't swap if the bits are same
+ UML_CALLHc(block, (data & MODE1_SRD2H) ? COND_Z : COND_NZ, *m_swap_dag2_4_7);
// DAG2 regs 0-3
- UML_TEST(block, MODE1, 0x40); // don't swap if the bits are same
- UML_CALLHc(block, (data & 0x40) ? COND_Z : COND_NZ, *m_swap_dag2_0_3);
+ UML_TEST(block, I2, MODE1_SRD2L); // don't swap if the bits are same
+ UML_CALLHc(block, (data & MODE1_SRD2L) ? COND_Z : COND_NZ, *m_swap_dag2_0_3);
// REG 8-15
- UML_TEST(block, MODE1, 0x80); // don't swap if the bits are same
- UML_CALLHc(block, (data & 0x80) ? COND_Z : COND_NZ, *m_swap_r8_15);
+ UML_TEST(block, I2, MODE1_SRRFH); // don't swap if the bits are same
+ UML_CALLHc(block, (data & MODE1_SRRFH) ? COND_Z : COND_NZ, *m_swap_r8_15);
// REG 0-7
- UML_TEST(block, MODE1, 0x400); // don't swap if the bits are same
- UML_CALLHc(block, (data & 0x400) ? COND_Z : COND_NZ, *m_swap_r0_7);
-
- UML_MOV(block, MODE1, data);
+ UML_TEST(block, I2, MODE1_SRRFL); // don't swap if the bits are same
+ UML_CALLHc(block, (data & MODE1_SRRFL) ? COND_Z : COND_NZ, *m_swap_r0_7);
+
+ // short word sign extension
+ UML_TEST(block, I2, MODE1_SSE); // don't update if the bits are same
+ UML_JMPc(block, (data & MODE1_SSE) ? COND_NZ : COND_Z, skip_sse);
+ UML_CALLC(block, cfuncs::update_sse, this);
+ UML_LABEL(block, skip_sse);
}
void adsp21062_device::generate_set_mode1_imm(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint32_t data)
@@ -2057,7 +2148,7 @@ void adsp21062_device::generate_write_ureg(drcuml_block &block, compiler_state &
UML_AND(block, I0, I0, 0x1f);
UML_CMP(block, I0, 31);
UML_JMPc(block, COND_B, no_overflow);
- UML_CALLC(block, cfunc_pcstack_overflow, this);
+ UML_CALLC(block, cfuncs::pcstack_overflow, this);
UML_LABEL(block, no_overflow);
UML_CMP(block, I1, I0);
UML_JMPc(block, COND_E, done);
@@ -2124,19 +2215,19 @@ void adsp21062_device::generate_write_ureg(drcuml_block &block, compiler_state &
UML_AND(block, I1, I1, imm ? data : I0);
UML_TEST(block, I1, 1 << (15 + 0));
UML_JMPc(block, COND_Z, skip0);
- UML_CALLC(block, cfunc_update_flag_out<0>, this);
+ UML_CALLC(block, cfuncs::update_flag_out<0>, this);
UML_LABEL(block, skip0);
UML_TEST(block, I1, 1 << (15 + 1));
UML_JMPc(block, COND_Z, skip1);
- UML_CALLC(block, cfunc_update_flag_out<1>, this);
+ UML_CALLC(block, cfuncs::update_flag_out<1>, this);
UML_LABEL(block, skip1);
UML_TEST(block, I1, 1 << (15 + 2));
UML_JMPc(block, COND_Z, skip2);
- UML_CALLC(block, cfunc_update_flag_out<2>, this);
+ UML_CALLC(block, cfuncs::update_flag_out<2>, this);
UML_LABEL(block, skip2);
UML_TEST(block, I1, 1 << (15 + 3));
UML_JMPc(block, COND_Z, skip3);
- UML_CALLC(block, cfunc_update_flag_out<3>, this);
+ UML_CALLC(block, cfuncs::update_flag_out<3>, this);
UML_LABEL(block, skip3);
break;
}
@@ -2208,19 +2299,19 @@ void adsp21062_device::generate_write_ureg(drcuml_block &block, compiler_state &
UML_AND(block, I0, I0, I1);
UML_TEST(block, I0, FLG0);
UML_JMPc(block, COND_Z, skip0);
- UML_CALLC(block, cfunc_update_flag_out<0>, this);
+ UML_CALLC(block, cfuncs::update_flag_out<0>, this);
UML_LABEL(block, skip0);
UML_TEST(block, I0, FLG1);
UML_JMPc(block, COND_Z, skip1);
- UML_CALLC(block, cfunc_update_flag_out<1>, this);
+ UML_CALLC(block, cfuncs::update_flag_out<1>, this);
UML_LABEL(block, skip1);
UML_TEST(block, I0, FLG2);
UML_JMPc(block, COND_Z, skip2);
- UML_CALLC(block, cfunc_update_flag_out<2>, this);
+ UML_CALLC(block, cfuncs::update_flag_out<2>, this);
UML_LABEL(block, skip2);
UML_TEST(block, I0, FLG3);
UML_JMPc(block, COND_Z, skip3);
- UML_CALLC(block, cfunc_update_flag_out<3>, this);
+ UML_CALLC(block, cfuncs::update_flag_out<3>, this);
UML_LABEL(block, skip3);
break;
}
@@ -2814,7 +2905,7 @@ bool adsp21062_device::generate_opcode(drcuml_block &block, compiler_state &comp
uml::code_label const skip = compiler.labelnum++;
UML_TEST(block, I0, 1 << (15 + 0));
UML_JMPc(block, COND_NZ, skip);
- UML_CALLC(block, cfunc_update_flag_out<0>, this);
+ UML_CALLC(block, cfuncs::update_flag_out<0>, this);
UML_LABEL(block, skip);
}
if (BIT(data, 15 + 1))
@@ -2822,7 +2913,7 @@ bool adsp21062_device::generate_opcode(drcuml_block &block, compiler_state &comp
uml::code_label const skip = compiler.labelnum++;
UML_TEST(block, I0, 1 << (15 + 1));
UML_JMPc(block, COND_NZ, skip);
- UML_CALLC(block, cfunc_update_flag_out<1>, this);
+ UML_CALLC(block, cfuncs::update_flag_out<1>, this);
UML_LABEL(block, skip);
}
if (BIT(data, 15 + 2))
@@ -2830,7 +2921,7 @@ bool adsp21062_device::generate_opcode(drcuml_block &block, compiler_state &comp
uml::code_label const skip = compiler.labelnum++;
UML_TEST(block, I0, 1 << (15 + 2));
UML_JMPc(block, COND_NZ, skip);
- UML_CALLC(block, cfunc_update_flag_out<2>, this);
+ UML_CALLC(block, cfuncs::update_flag_out<2>, this);
UML_LABEL(block, skip);
}
if (BIT(data, 15 + 3))
@@ -2838,7 +2929,7 @@ bool adsp21062_device::generate_opcode(drcuml_block &block, compiler_state &comp
uml::code_label const skip = compiler.labelnum++;
UML_TEST(block, I0, 1 << (15 + 3));
UML_JMPc(block, COND_NZ, skip);
- UML_CALLC(block, cfunc_update_flag_out<3>, this);
+ UML_CALLC(block, cfuncs::update_flag_out<3>, this);
UML_LABEL(block, skip);
}
}
@@ -2897,7 +2988,7 @@ bool adsp21062_device::generate_opcode(drcuml_block &block, compiler_state &comp
uml::code_label const skip = compiler.labelnum++;
UML_TEST(block, I0, FLG0);
UML_JMPc(block, COND_Z, skip);
- UML_CALLC(block, cfunc_update_flag_out<0>, this);
+ UML_CALLC(block, cfuncs::update_flag_out<0>, this);
UML_LABEL(block, skip);
}
if (data & FLG1)
@@ -2905,7 +2996,7 @@ bool adsp21062_device::generate_opcode(drcuml_block &block, compiler_state &comp
uml::code_label const skip = compiler.labelnum++;
UML_TEST(block, I0, FLG1);
UML_JMPc(block, COND_Z, skip);
- UML_CALLC(block, cfunc_update_flag_out<1>, this);
+ UML_CALLC(block, cfuncs::update_flag_out<1>, this);
UML_LABEL(block, skip);
}
if (data & FLG2)
@@ -2913,7 +3004,7 @@ bool adsp21062_device::generate_opcode(drcuml_block &block, compiler_state &comp
uml::code_label const skip = compiler.labelnum++;
UML_TEST(block, I0, FLG2);
UML_JMPc(block, COND_Z, skip);
- UML_CALLC(block, cfunc_update_flag_out<2>, this);
+ UML_CALLC(block, cfuncs::update_flag_out<2>, this);
UML_LABEL(block, skip);
}
if (data & FLG3)
@@ -2921,7 +3012,7 @@ bool adsp21062_device::generate_opcode(drcuml_block &block, compiler_state &comp
uml::code_label const skip = compiler.labelnum++;
UML_TEST(block, I0, FLG3);
UML_JMPc(block, COND_Z, skip);
- UML_CALLC(block, cfunc_update_flag_out<3>, this);
+ UML_CALLC(block, cfuncs::update_flag_out<3>, this);
UML_LABEL(block, skip);
}
if (data & 0xff000000)
@@ -3009,7 +3100,7 @@ bool adsp21062_device::generate_opcode(drcuml_block &block, compiler_state &comp
uml::code_label const skip = compiler.labelnum++;
UML_TEST(block, I0, FLG0);
UML_JMPc(block, COND_Z, skip);
- UML_CALLC(block, cfunc_update_flag_out<0>, this);
+ UML_CALLC(block, cfuncs::update_flag_out<0>, this);
UML_LABEL(block, skip);
}
if (data & FLG1)
@@ -3017,7 +3108,7 @@ bool adsp21062_device::generate_opcode(drcuml_block &block, compiler_state &comp
uml::code_label const skip = compiler.labelnum++;
UML_TEST(block, I0, FLG1);
UML_JMPc(block, COND_Z, skip);
- UML_CALLC(block, cfunc_update_flag_out<1>, this);
+ UML_CALLC(block, cfuncs::update_flag_out<1>, this);
UML_LABEL(block, skip);
}
if (data & FLG2)
@@ -3025,7 +3116,7 @@ bool adsp21062_device::generate_opcode(drcuml_block &block, compiler_state &comp
uml::code_label const skip = compiler.labelnum++;
UML_TEST(block, I0, FLG2);
UML_JMPc(block, COND_Z, skip);
- UML_CALLC(block, cfunc_update_flag_out<2>, this);
+ UML_CALLC(block, cfuncs::update_flag_out<2>, this);
UML_LABEL(block, skip);
}
if (data & FLG3)
@@ -3033,7 +3124,7 @@ bool adsp21062_device::generate_opcode(drcuml_block &block, compiler_state &comp
uml::code_label const skip = compiler.labelnum++;
UML_TEST(block, I0, FLG3);
UML_JMPc(block, COND_Z, skip);
- UML_CALLC(block, cfunc_update_flag_out<3>, this);
+ UML_CALLC(block, cfuncs::update_flag_out<3>, this);
UML_LABEL(block, skip);
}
if (data & 0xff000000)
@@ -3785,7 +3876,7 @@ void adsp21062_device::generate_unimplemented_compute(drcuml_block &block, compi
{
UML_MOV(block, mem(&m_core->pc), desc->pc);
UML_DMOV(block, mem(&m_core->arg64), desc->opptr);
- UML_CALLC(block, cfunc_unimplemented_compute, this);
+ UML_CALLC(block, cfuncs::unimplemented_compute, this);
}
void adsp21062_device::generate_compute(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc)
@@ -5628,7 +5719,7 @@ void adsp21062_device::generate_shift_imm(drcuml_block &block, compiler_state &c
case 0x1b: // Rn = Rn OR FDEP Rx BY <bit6>:<len6> (SE)
UML_MOV(block, mem(&m_core->pc), desc->pc);
UML_DMOV(block, mem(&m_core->arg64), desc->opptr);
- UML_CALLC(block, cfunc_unimplemented_shiftimm, this);
+ UML_CALLC(block, cfuncs::unimplemented_shiftimm, this);
break;
case 0x00: // LSHIFT Rx BY <data8>
@@ -5804,7 +5895,7 @@ void adsp21062_device::generate_shift_imm(drcuml_block &block, compiler_state &c
default:
UML_MOV(block, mem(&m_core->pc), desc->pc);
UML_DMOV(block, mem(&m_core->arg64), desc->opptr);
- UML_CALLC(block, cfunc_unimplemented_compute, this);
+ UML_CALLC(block, cfuncs::unimplemented_compute, this);
return;
}
}
diff --git a/src/devices/cpu/sharc/sharcfe.cpp b/src/devices/cpu/sharc/sharcfe.cpp
index 52f0a115bc1..387fe457eae 100644
--- a/src/devices/cpu/sharc/sharcfe.cpp
+++ b/src/devices/cpu/sharc/sharcfe.cpp
@@ -14,6 +14,133 @@
#include "cpu/drcfe.ipp"
+#include <iostream>
+
+
+void adsp21062_device::opcode_desc::log_flags(std::ostream &stream) const
+{
+ // branches
+ if (is_unconditional_branch())
+ stream << 'U';
+ else if (is_conditional_branch())
+ stream << 'C';
+ else
+ stream << '.';
+
+ // intrablock branches
+ stream << (intrablock_branch() ? 'i' : '.');
+
+ // branch targets
+ stream << (is_branch_target() ? 'B' : '.');
+
+ // delay slots
+ stream << (in_delay_slot() ? 'D' : '.');
+
+ // exceptions
+ if (will_cause_exception())
+ stream << 'E';
+ else if (can_cause_exception())
+ stream << 'e';
+ else
+ stream << '.';
+
+ // read/write
+ if (reads_memory())
+ stream << (writes_memory() ? '+' : 'R');
+ else if (writes_memory())
+ stream << 'W';
+ else
+ stream << '.';
+
+ // TLB validation
+ stream << (validate_tlb() ? 'V' : '.');
+
+ // redispatch
+ stream << (redispatch() ? 'R' : '.');
+}
+
+void adsp21062_device::opcode_desc::log_registers_used(std::ostream &stream) const
+{
+ stream << "[use:";
+ log_register_list(stream, regin, nullptr);
+ stream << ']';
+}
+
+void adsp21062_device::opcode_desc::log_registers_modified(std::ostream &stream) const
+{
+ stream << "[mod:";
+ log_register_list(stream, regout, &regreq);
+ stream << ']';
+}
+
+void adsp21062_device::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_AZ, "AZ");
+ log_bit(REG_AV, "AV");
+ log_bit(REG_AN, "AN");
+ log_bit(REG_AC, "AC");
+ log_bit(REG_AS, "AS");
+ log_bit(REG_AI, "AI");
+ log_bit(REG_MN, "MN");
+ log_bit(REG_MV, "MV");
+ log_bit(REG_MU, "MU");
+ log_bit(REG_MI, "MI");
+ log_bit(REG_AF, "AF");
+ log_bit(REG_SV, "SV");
+ log_bit(REG_SZ, "SZ");
+ log_bit(REG_SS, "SS");
+ log_bit(REG_BTF, "BTF");
+
+ auto const log_dag =
+ [&stream, &count, &reglist, &regnostarlist] (size_t d, size_t p, char name)
+ {
+ for (int regnum = 0; regnum < 16; regnum++)
+ {
+ size_t const bit = ((regnum < 8) ? d : p) + (regnum & 0x7);
+ if (reglist[bit])
+ {
+ if (count++)
+ stream << ',';
+ stream << name << regnum;
+ if (regnostarlist && !(*regnostarlist)[bit])
+ stream << '*';
+ }
+ }
+ };
+
+ log_dag(REG_DM_I0, REG_PM_I0, 'I');
+ log_dag(REG_DM_M0, REG_PM_M0, 'M');
+ log_dag(REG_DM_L0, REG_PM_L0, 'L');
+ log_dag(REG_DM_B0, REG_PM_B0, 'B');
+}
+
adsp21062_device::frontend::frontend(adsp21062_device *sharc, uint32_t window_start, uint32_t window_end, uint32_t max_sequence)
: drc_frontend_base(sharc->space_config(AS_PROGRAM)->page_shift(), window_start, window_end, max_sequence)
@@ -70,11 +197,12 @@ void adsp21062_device::frontend::insert_loop(const LOOP_DESCRIPTOR &loopdesc)
opcode_desc::extra_flags userflags;
userflags.reset();
if (flags & AZ) { userflags.set(opcode_desc::ASTAT_DELAY_COPY_AZ); }
- if (flags & AN) { userflags.set(opcode_desc::ASTAT_DELAY_COPY_AN); }
if (flags & AV) { userflags.set(opcode_desc::ASTAT_DELAY_COPY_AV); }
+ if (flags & AN) { userflags.set(opcode_desc::ASTAT_DELAY_COPY_AN); }
if (flags & AC) { userflags.set(opcode_desc::ASTAT_DELAY_COPY_AC); }
if (flags & MN) { userflags.set(opcode_desc::ASTAT_DELAY_COPY_MN); }
if (flags & MV) { userflags.set(opcode_desc::ASTAT_DELAY_COPY_MV); }
+ if (flags & AF) { userflags.set(opcode_desc::ASTAT_DELAY_COPY_AF); }
if (flags & SV) { userflags.set(opcode_desc::ASTAT_DELAY_COPY_SV); }
if (flags & SZ) { userflags.set(opcode_desc::ASTAT_DELAY_COPY_SZ); }
if (flags & BTF) { userflags.set(opcode_desc::ASTAT_DELAY_COPY_BTF); }
@@ -513,76 +641,31 @@ bool adsp21062_device::frontend::describe(opcode_desc &desc, const opcode_desc *
if (data & MV) desc.set_mv_modified();
if (data & MU) desc.set_mu_modified();
if (data & MI) desc.set_mi_modified();
+ if (data & AF) desc.set_af_modified();
if (data & SV) desc.set_sv_modified();
if (data & SZ) desc.set_sz_modified();
if (data & SS) desc.set_ss_modified();
if (data & BTF) desc.set_btf_modified();
- if (data & AF) desc.set_af_modified();
}
break;
case 2: // TOGGLE
if (sreg == 0x7c) // ASTAT
{
- if (data & AZ)
- {
- desc.set_az_used(); desc.set_az_modified();
- }
- if (data & AV)
- {
- desc.set_av_used(); desc.set_av_modified();
- }
- if (data & AN)
- {
- desc.set_an_used(); desc.set_an_modified();
- }
- if (data & AC)
- {
- desc.set_ac_used(); desc.set_ac_modified();
- }
- if (data & AS)
- {
- desc.set_as_used(); desc.set_as_modified();
- }
- if (data & AI)
- {
- desc.set_ai_used(); desc.set_ai_modified();
- }
- if (data & MN)
- {
- desc.set_mn_used(); desc.set_mn_modified();
- }
- if (data & MV)
- {
- desc.set_mv_used(); desc.set_mv_modified();
- }
- if (data & MU)
- {
- desc.set_mu_used(); desc.set_mu_modified();
- }
- if (data & MI)
- {
- desc.set_mi_used(); desc.set_mi_modified();
- }
- if (data & SV)
- {
- desc.set_sv_used(); desc.set_sv_modified();
- }
- if (data & SZ)
- {
- desc.set_sz_used(); desc.set_sz_modified();
- }
- if (data & SS)
- {
- desc.set_ss_used(); desc.set_ss_modified();
- }
- if (data & BTF)
- {
- desc.set_btf_used(); desc.set_btf_modified();
- }
- if (data & AF)
- {
- desc.set_af_used(); desc.set_af_modified();
- }
+ if (data & AZ) { desc.set_az_used(); desc.set_az_modified(); }
+ if (data & AV) { desc.set_av_used(); desc.set_av_modified(); }
+ if (data & AN) { desc.set_an_used(); desc.set_an_modified(); }
+ if (data & AC) { desc.set_ac_used(); desc.set_ac_modified(); }
+ if (data & AS) { desc.set_as_used(); desc.set_as_modified(); }
+ if (data & AI) { desc.set_ai_used(); desc.set_ai_modified(); }
+ if (data & MN) { desc.set_mn_used(); desc.set_mn_modified(); }
+ if (data & MV) { desc.set_mv_used(); desc.set_mv_modified(); }
+ if (data & MU) { desc.set_mu_used(); desc.set_mu_modified(); }
+ if (data & MI) { desc.set_mi_used(); desc.set_mi_modified(); }
+ if (data & AF) { desc.set_af_used(); desc.set_af_modified(); }
+ if (data & SV) { desc.set_sv_used(); desc.set_sv_modified(); }
+ if (data & SZ) { desc.set_sz_used(); desc.set_sz_modified(); }
+ if (data & SS) { desc.set_ss_used(); desc.set_ss_modified(); }
+ if (data & BTF) { desc.set_btf_used(); desc.set_btf_modified(); }
}
break;
@@ -1376,7 +1459,6 @@ bool adsp21062_device::frontend::describe_compute(opcode_desc &desc, uint64_t op
case 0xb6: // MRB = MRB + Rx * Ry (SSI)
case 0xbe: // MRB = MRB + Rx * Ry (SSF)
case 0xbf: // MRB = MRB + Rx * Ry (SSFR)
- break;
// TODO: track MRB?
desc.set_reg_used(rx);
desc.set_reg_used(ry);
@@ -1690,8 +1772,8 @@ bool adsp21062_device::frontend::describe_ureg_access(opcode_desc &desc, int reg
if (access == UREG_READ)
{
desc.set_az_used();
- desc.set_an_used();
desc.set_av_used();
+ desc.set_an_used();
desc.set_ac_used();
desc.set_as_used();
desc.set_ai_used();
@@ -1699,11 +1781,11 @@ bool adsp21062_device::frontend::describe_ureg_access(opcode_desc &desc, int reg
desc.set_mv_used();
desc.set_mu_used();
desc.set_mi_used();
+ desc.set_af_used();
desc.set_sv_used();
desc.set_sz_used();
desc.set_ss_used();
desc.set_btf_used();
- desc.set_af_used();
}
else
{
@@ -1711,7 +1793,6 @@ bool adsp21062_device::frontend::describe_ureg_access(opcode_desc &desc, int reg
desc.set_mult_flags_modified();
desc.set_shift_flags_modified();
desc.set_btf_modified();
- desc.set_af_modified();
}
break;
@@ -1782,8 +1863,8 @@ void adsp21062_device::frontend::describe_if_condition(opcode_desc &desc, int co
switch (condition)
{
case 0x00: desc.set_az_used(); break; // EQ
- case 0x01: desc.set_az_used(); desc.set_an_used(); break; // LT
- case 0x02: desc.set_az_used(); desc.set_an_used(); break; // LE
+ case 0x01: desc.set_az_used(); desc.set_av_used(); desc.set_an_used(); desc.set_af_used(); break; // LT
+ case 0x02: desc.set_az_used(); desc.set_av_used(); desc.set_an_used(); desc.set_af_used(); break; // LE
case 0x03: desc.set_ac_used(); break; // AC
case 0x04: desc.set_av_used(); break; // AV
case 0x05: desc.set_mv_used(); break; // MV
@@ -1792,8 +1873,8 @@ void adsp21062_device::frontend::describe_if_condition(opcode_desc &desc, int co
case 0x08: desc.set_sz_used(); break; // SZ
case 0x0d: desc.set_btf_used(); break; // TF
case 0x10: desc.set_az_used(); break; // NOT EQUAL
- case 0x11: desc.set_az_used(); desc.set_an_used(); break; // GE
- case 0x12: desc.set_az_used(); desc.set_an_used(); break; // GT
+ case 0x11: desc.set_az_used(); desc.set_av_used(); desc.set_an_used(); desc.set_af_used(); break; // GE
+ case 0x12: desc.set_az_used(); desc.set_av_used(); desc.set_an_used(); desc.set_af_used(); break; // GT
case 0x13: desc.set_ac_used(); break; // NOT AC
case 0x14: desc.set_av_used(); break; // NOT AV
case 0x15: desc.set_mv_used(); break; // NOT MV
diff --git a/src/devices/cpu/sharc/sharcfe.h b/src/devices/cpu/sharc/sharcfe.h
index a3493d9cd91..0888b1ed01b 100644
--- a/src/devices/cpu/sharc/sharcfe.h
+++ b/src/devices/cpu/sharc/sharcfe.h
@@ -17,6 +17,7 @@
#include <cassert>
#include <bitset>
+#include <iosfwd>
class adsp21062_device::opcode_desc : public opcode_desc_base<opcode_desc, 96>
@@ -26,11 +27,12 @@ public:
{
LOOP = 0,
ASTAT_DELAY_COPY_AZ,
+ ASTAT_DELAY_COPY_AV,
ASTAT_DELAY_COPY_AN,
ASTAT_DELAY_COPY_AC,
- ASTAT_DELAY_COPY_AV,
ASTAT_DELAY_COPY_MV,
ASTAT_DELAY_COPY_MN,
+ ASTAT_DELAY_COPY_AF,
ASTAT_DELAY_COPY_SV,
ASTAT_DELAY_COPY_SZ,
ASTAT_DELAY_COPY_BTF,
@@ -69,6 +71,8 @@ public:
void set_mu_modified() { regout.set(REG_MU); }
void set_mi_used() { regin.set(REG_MI); }
void set_mi_modified() { regout.set(REG_MI); }
+ void set_af_used() { regin.set(REG_AF); }
+ void set_af_modified() { regout.set(REG_AF); }
void set_sv_used() { regin.set(REG_SV); }
void set_sv_modified() { regout.set(REG_SV); }
void set_sz_used() { regin.set(REG_SZ); }
@@ -77,35 +81,34 @@ public:
void set_ss_modified() { regout.set(REG_SS); }
void set_btf_used() { regin.set(REG_BTF); }
void set_btf_modified() { regout.set(REG_BTF); }
- void set_af_used() { regin.set(REG_AF); }
- void set_af_modified() { regout.set(REG_AF); }
-
- void set_pm_i_used(unsigned x) { regin.set(REG_PM_I0 + x); }
- void set_pm_i_modified(unsigned x) { regout.set(REG_PM_I0 + x); }
- void set_pm_m_used(unsigned x) { regin.set(REG_PM_M0 + x); }
- void set_pm_m_modified(unsigned x) { regout.set(REG_PM_M0 + x); }
- void set_pm_b_used(unsigned x) { regin.set(REG_PM_B0 + x); }
- void set_pm_b_modified(unsigned x) { regout.set(REG_PM_B0 + x); }
- void set_pm_l_used(unsigned x) { regin.set(REG_PM_L0 + x); }
- void set_pm_l_modified(unsigned x) { regout.set(REG_PM_L0 + x); }
void set_dm_i_used(unsigned x) { regin.set(REG_DM_I0 + x); }
void set_dm_i_modified(unsigned x) { regout.set(REG_DM_I0 + x); }
void set_dm_m_used(unsigned x) { regin.set(REG_DM_M0 + x); }
void set_dm_m_modified(unsigned x) { regout.set(REG_DM_M0 + x); }
- void set_dm_b_used(unsigned x) { regin.set(REG_DM_B0 + x); }
- void set_dm_b_modified(unsigned x) { regout.set(REG_DM_B0 + x); }
void set_dm_l_used(unsigned x) { regin.set(REG_DM_L0 + x); }
void set_dm_l_modified(unsigned x) { regout.set(REG_DM_L0 + x); }
+ void set_dm_b_used(unsigned x) { regin.set(REG_DM_B0 + x); }
+ void set_dm_b_modified(unsigned x) { regout.set(REG_DM_B0 + x); }
+
+ void set_pm_i_used(unsigned x) { regin.set(REG_PM_I0 + x); }
+ void set_pm_i_modified(unsigned x) { regout.set(REG_PM_I0 + x); }
+ void set_pm_m_used(unsigned x) { regin.set(REG_PM_M0 + x); }
+ void set_pm_m_modified(unsigned x) { regout.set(REG_PM_M0 + x); }
+ void set_pm_l_used(unsigned x) { regin.set(REG_PM_L0 + x); }
+ void set_pm_l_modified(unsigned x) { regout.set(REG_PM_L0 + x); }
+ void set_pm_b_used(unsigned x) { regin.set(REG_PM_B0 + x); }
+ void set_pm_b_modified(unsigned x) { regout.set(REG_PM_B0 + x); }
void set_alu_flags_modified()
{
set_az_modified();
- set_an_modified();
set_av_modified();
+ set_an_modified();
set_ac_modified();
set_as_modified();
set_ai_modified();
+ set_af_modified();
}
void set_mult_flags_modified()
@@ -118,8 +121,8 @@ public:
void set_shift_flags_modified()
{
- set_sz_modified();
set_sv_modified();
+ set_sz_modified();
set_ss_modified();
}
@@ -133,11 +136,11 @@ public:
bool mv_calc_required() const { return regreq[REG_MV] || in_delay_slot(); }
bool mu_calc_required() const { return regreq[REG_MU] || in_delay_slot(); }
bool mi_calc_required() const { return regreq[REG_MI] || in_delay_slot(); }
+ bool af_calc_required() const { return regreq[REG_AF] || in_delay_slot(); }
bool sv_calc_required() const { return regreq[REG_SV] || in_delay_slot(); }
bool sz_calc_required() const { return regreq[REG_SZ] || in_delay_slot(); }
bool ss_calc_required() const { return regreq[REG_SS] || in_delay_slot(); }
bool btf_calc_required() const { return regreq[REG_BTF] || in_delay_slot(); }
- bool af_calc_required() const { return regreq[REG_AF] || in_delay_slot(); }
void set_loop() { m_extra_flags.set(LOOP); }
void set_astat_delay_copy_az() { m_extra_flags.set(ASTAT_DELAY_COPY_AZ); }
@@ -182,6 +185,10 @@ public:
m_extra_flags.reset();
}
+ 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
{
@@ -197,25 +204,27 @@ private:
REG_MV,
REG_MU,
REG_MI,
+ REG_AF,
REG_SV,
REG_SZ,
REG_SS,
REG_BTF,
- REG_AF,
- REG_PM_I0,
- REG_PM_M0 = REG_PM_I0 + 8,
- REG_PM_B0 = REG_PM_M0 + 8,
- REG_PM_L0 = REG_PM_B0 + 8,
-
- REG_DM_I0 = REG_PM_L0 + 8,
+ REG_DM_I0,
REG_DM_M0 = REG_DM_I0 + 8,
- REG_DM_B0 = REG_DM_M0 + 8,
- REG_DM_L0 = REG_DM_B0 + 8,
+ REG_DM_L0 = REG_DM_M0 + 8,
+ REG_DM_B0 = REG_DM_L0 + 8,
- REG_COUNT = REG_DM_L0 + 8
+ REG_PM_I0 = REG_DM_B0 + 8,
+ REG_PM_M0 = REG_PM_I0 + 8,
+ REG_PM_L0 = REG_PM_M0 + 8,
+ REG_PM_B0 = REG_PM_L0 + 8,
+
+ REG_COUNT = REG_PM_B0 + 8
};
+ static void log_register_list(std::ostream &stream, const regmask &reglist, const regmask *regnostarlist);
+
extra_flags m_extra_flags;
};
diff --git a/src/devices/cpu/sharc/sharcops.hxx b/src/devices/cpu/sharc/sharcops.hxx
index eff2b6eb846..9c4956a5a2f 100644
--- a/src/devices/cpu/sharc/sharcops.hxx
+++ b/src/devices/cpu/sharc/sharcops.hxx
@@ -81,30 +81,30 @@ void adsp21062_device::add_systemreg_write_latency_effect(int sysreg, uint32_t d
void adsp21062_device::systemreg_write_latency_effect()
{
- uint32_t data = m_core->systemreg_latency_data;
- uint32_t old_data = m_core->systemreg_previous_data;
+ uint32_t const data = m_core->systemreg_latency_data;
+ uint32_t const old_data = m_core->systemreg_previous_data;
switch (m_core->systemreg_latency_reg)
{
case 0xb: /* MODE1 */
{
- uint32_t oldreg = old_data;
+ uint32_t const diff = data ^ old_data;
m_core->mode1 = data;
- if ((data & 0x1) != (oldreg & 0x1))
+ if (diff & MODE1_BR8)
{
throw emu_fatalerror("%s: systemreg_latency_op: enable I8 bit-reversing", tag());
}
- if ((data & 0x2) != (oldreg & 0x2))
+ if (diff & MODE1_BR0)
{
throw emu_fatalerror("%s: systemreg_latency_op: enable I0 bit-reversing", tag());
}
- if ((data & 0x4) != (oldreg & 0x4))
+ if (diff & MODE1_SRCU)
{
throw emu_fatalerror("%s: systemreg_latency_op: enable MR alternate", tag());
}
- if ((data & 0x8) != (oldreg & 0x8)) /* Switch DAG1 7-4 */
+ if (diff & MODE1_SRD1H) // Switch DAG1 7-4
{
using std::swap;
swap(m_core->dag1.i[4], m_core->dag1_alt.i[4]);
@@ -124,7 +124,7 @@ void adsp21062_device::systemreg_write_latency_effect()
swap(m_core->dag1.b[6], m_core->dag1_alt.b[6]);
swap(m_core->dag1.b[7], m_core->dag1_alt.b[7]);
}
- if ((data & 0x10) != (oldreg & 0x10)) /* Switch DAG1 3-0 */
+ if (diff & MODE1_SRD1L) // Switch DAG1 3-0
{
using std::swap;
swap(m_core->dag1.i[0], m_core->dag1_alt.i[0]);
@@ -144,7 +144,7 @@ void adsp21062_device::systemreg_write_latency_effect()
swap(m_core->dag1.b[2], m_core->dag1_alt.b[2]);
swap(m_core->dag1.b[3], m_core->dag1_alt.b[3]);
}
- if ((data & 0x20) != (oldreg & 0x20)) /* Switch DAG2 15-12 */
+ if (diff & MODE1_SRD2H) // Switch DAG2 15-12
{
using std::swap;
swap(m_core->dag2.i[4], m_core->dag2_alt.i[4]);
@@ -164,7 +164,7 @@ void adsp21062_device::systemreg_write_latency_effect()
swap(m_core->dag2.b[6], m_core->dag2_alt.b[6]);
swap(m_core->dag2.b[7], m_core->dag2_alt.b[7]);
}
- if ((data & 0x40) != (oldreg & 0x40)) /* Switch DAG2 11-8 */
+ if (diff & MODE1_SRD2L) // Switch DAG2 11-8
{
using std::swap;
swap(m_core->dag2.i[0], m_core->dag2_alt.i[0]);
@@ -184,18 +184,25 @@ void adsp21062_device::systemreg_write_latency_effect()
swap(m_core->dag2.b[2], m_core->dag2_alt.b[2]);
swap(m_core->dag2.b[3], m_core->dag2_alt.b[3]);
}
- if ((data & 0x80) != (oldreg & 0x80))
+ if (diff & MODE1_SRRFH)
{
using std::swap;
- for (int i=8; i<16; i++)
+ for (int i = 8; i < 16; i++)
swap(m_core->r[i].r, m_core->reg_alt[i].r);
}
- if ((data & 0x400) != (oldreg & 0x400))
+ if (diff & MODE1_SRRFL)
{
using std::swap;
- for (int i=0; i<8; i++)
+ for (int i = 0; i < 8; i++)
swap(m_core->r[i].r, m_core->reg_alt[i].r);
}
+ if (diff & MODE1_SSE) // Short word sign extension
+ {
+ if (data & MODE1_SSE)
+ m_dm_short_view.select(0);
+ else
+ m_dm_short_view.disable();
+ }
break;
}
default: throw emu_fatalerror("%s: systemreg_latency_op: unknown register %02X at %08X\n", tag(), m_core->systemreg_latency_reg, m_core->pc);
diff --git a/src/devices/cpu/uml.h b/src/devices/cpu/uml.h
index 1431fb3b638..f455546fc19 100644
--- a/src/devices/cpu/uml.h
+++ b/src/devices/cpu/uml.h
@@ -326,7 +326,8 @@ namespace uml {
static parameter make_memory(void const *base) { return parameter(PTYPE_MEMORY, reinterpret_cast<parameter_value>(const_cast<void *>(base))); }
static parameter make_size(operand_size size) { assert(size >= SIZE_BYTE && size <= SIZE_QWORD); return parameter(PTYPE_SIZE, size); }
static parameter make_string(char const *string) { return parameter(PTYPE_STRING, reinterpret_cast<parameter_value>(const_cast<char *>(string))); }
- static parameter make_cfunc(c_function func) { return parameter(PTYPE_C_FUNCTION, reinterpret_cast<parameter_value>(func)); }
+ template <typename T> static parameter make_cfunc(void (*func)(T *)) { return parameter(PTYPE_C_FUNCTION, parameter_value(reinterpret_cast<uintptr_t>(func))); }
+ template <typename T> static parameter make_cfunc(void (*func)(T &)) { return parameter(PTYPE_C_FUNCTION, parameter_value(reinterpret_cast<uintptr_t>(func))); }
static parameter make_rounding(float_rounding_mode mode) { assert(mode >= ROUND_TRUNC && mode <= ROUND_DEFAULT); return parameter(PTYPE_ROUNDING, mode); }
// operators
@@ -345,7 +346,7 @@ namespace uml {
memory_space space() const { assert(m_type == PTYPE_SIZE_SPACE); return memory_space(m_value >> 4); }
code_handle &handle() const { assert(m_type == PTYPE_CODE_HANDLE); return *reinterpret_cast<code_handle *>(m_value); }
code_label label() const { assert(m_type == PTYPE_CODE_LABEL); return code_label(m_value); }
- c_function cfunc() const { assert(m_type == PTYPE_C_FUNCTION); return reinterpret_cast<c_function>(m_value); }
+ c_function cfunc() const { assert(m_type == PTYPE_C_FUNCTION); return reinterpret_cast<c_function>(uintptr_t(m_value)); }
float_rounding_mode rounding() const { assert(m_type == PTYPE_ROUNDING); return float_rounding_mode(m_value); }
char const *string() const { assert(m_type == PTYPE_STRING); return reinterpret_cast<char const *>(m_value); }
@@ -465,8 +466,8 @@ namespace uml {
void callh(condition_t cond, code_handle &handle) { configure(OP_CALLH, 4, handle, cond); }
void ret() { configure(OP_RET, 4); }
void ret(condition_t cond) { configure(OP_RET, 4, cond); }
- void callc(c_function func, void *ptr) { configure(OP_CALLC, 4, parameter::make_cfunc(func), parameter::make_memory(ptr)); }
- void callc(condition_t cond, c_function func, void *ptr) { configure(OP_CALLC, 4, parameter::make_cfunc(func), parameter::make_memory(ptr), cond); }
+ template <typename T> void callc(T func, void *ptr) { configure(OP_CALLC, 4, parameter::make_cfunc(func), parameter::make_memory(ptr)); }
+ template <typename T> void callc(condition_t cond, T func, void *ptr) { configure(OP_CALLC, 4, parameter::make_cfunc(func), parameter::make_memory(ptr), cond); }
void recover(parameter dst, parameter mapvar) { assert(mapvar.is_mapvar()); configure(OP_RECOVER, 4, dst, mapvar); }
// internal register operations