diff options
| author | 2026-03-07 03:20:05 +1100 | |
|---|---|---|
| committer | 2026-03-07 03:22:56 +1100 | |
| commit | 1f7fa43c3d2692d3523e8b72a24e04fff7c30a57 (patch) | |
| tree | 404cc315d6e97ea55456270d3e2195b661a35a2a /src | |
| parent | 0edf02aea873379876de8b42a8cfd00bd1967cc9 (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.cpp | 47 | ||||
| -rw-r--r-- | src/devices/cpu/e132xs/e1fe.cpp | 2 | ||||
| -rw-r--r-- | src/devices/cpu/powerpc/ppcfe.cpp | 2 | ||||
| -rw-r--r-- | src/devices/cpu/sh/sh_fe.cpp | 2 | ||||
| -rw-r--r-- | src/devices/cpu/sharc/sharc.cpp | 75 | ||||
| -rw-r--r-- | src/devices/cpu/sharc/sharc.h | 32 | ||||
| -rw-r--r-- | src/devices/cpu/sharc/sharcdrc.cpp | 375 | ||||
| -rw-r--r-- | src/devices/cpu/sharc/sharcfe.cpp | 221 | ||||
| -rw-r--r-- | src/devices/cpu/sharc/sharcfe.h | 63 | ||||
| -rw-r--r-- | src/devices/cpu/sharc/sharcops.hxx | 35 | ||||
| -rw-r--r-- | src/devices/cpu/uml.h | 9 |
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, ®req); + stream << ']'; +} + +void adsp21062_device::opcode_desc::log_register_list(std::ostream &stream, const regmask ®list, 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, ®list, ®nostarlist] (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, ®list, ®nostarlist] (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 ®list, 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 |
