summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2026-03-02 09:25:23 +1100
committer Vas Crabb <vas@vastheman.com>2026-03-02 09:25:23 +1100
commit366b485b037b404a4a71f1caa77a4cacb83e17ef (patch)
tree5a952cf72bc53d6c1032738f21725e8ae55f152e
parentac492c02708b92ce76400214204a4fa9713d0a1a (diff)
Allow recompiling CPU cores to define their own opcode descriptions.
The base opcode description now only has the parts that are used by the base recompiler front-end. CPU cores are free to define their own extensions as they see fit without being limited to pre-defined fields. The base recompiler front-end is now a template, eliminating the virtual member functions. It no longer has any dependencies on libemu, which paves the way to decoupling the recompiler front-ends and allowing the instruction analysis to be tested without the rest of the emulator. Also added a compile-time option to disable ASTAT flag update elision in the SHARC recompiler, and fixed some recompiler front-end bugs.
-rw-r--r--scripts/src/cpu.lua5
-rw-r--r--src/devices/cpu/drcfe.h195
-rw-r--r--src/devices/cpu/drcfe.ipp (renamed from src/devices/cpu/drcfe.cpp)220
-rw-r--r--src/devices/cpu/dsp16/dsp16.h2
-rw-r--r--src/devices/cpu/dsp16/dsp16fe.cpp138
-rw-r--r--src/devices/cpu/dsp16/dsp16fe.h50
-rw-r--r--src/devices/cpu/dspp/dspp.cpp15
-rw-r--r--src/devices/cpu/dspp/dspp.h31
-rw-r--r--src/devices/cpu/dspp/dsppdrc.cpp64
-rw-r--r--src/devices/cpu/dspp/dsppfe.cpp187
-rw-r--r--src/devices/cpu/dspp/dsppfe.h82
-rw-r--r--src/devices/cpu/e132xs/e132xs.cpp2
-rw-r--r--src/devices/cpu/e132xs/e132xs.h12
-rw-r--r--src/devices/cpu/e132xs/e132xsdrc.cpp72
-rw-r--r--src/devices/cpu/e132xs/e132xsdrc_ops.hxx140
-rw-r--r--src/devices/cpu/e132xs/e132xsfe.cpp958
-rw-r--r--src/devices/cpu/e132xs/e132xsfe.h56
-rw-r--r--src/devices/cpu/mb86235/mb86235.h20
-rw-r--r--src/devices/cpu/mb86235/mb86235defs.h20
-rw-r--r--src/devices/cpu/mb86235/mb86235drc.cpp117
-rw-r--r--src/devices/cpu/mb86235/mb86235fe.cpp520
-rw-r--r--src/devices/cpu/mb86235/mb86235fe.h165
-rw-r--r--src/devices/cpu/mips/mips3.cpp7
-rw-r--r--src/devices/cpu/mips/mips3.h44
-rw-r--r--src/devices/cpu/mips/mips3drc.cpp214
-rw-r--r--src/devices/cpu/mips/mips3fe.cpp349
-rw-r--r--src/devices/cpu/mips/mips3fe.h118
-rw-r--r--src/devices/cpu/powerpc/ppc.h7
-rw-r--r--src/devices/cpu/powerpc/ppcdrc.cpp209
-rw-r--r--src/devices/cpu/powerpc/ppcfe.cpp240
-rw-r--r--src/devices/cpu/powerpc/ppcfe.h106
-rw-r--r--src/devices/cpu/sh/sh.cpp159
-rw-r--r--src/devices/cpu/sh/sh.h47
-rw-r--r--src/devices/cpu/sh/sh2.cpp9
-rw-r--r--src/devices/cpu/sh/sh2.h19
-rw-r--r--src/devices/cpu/sh/sh2fe.cpp9
-rw-r--r--src/devices/cpu/sh/sh2fe.h28
-rw-r--r--src/devices/cpu/sh/sh4.cpp101
-rw-r--r--src/devices/cpu/sh/sh4.h40
-rw-r--r--src/devices/cpu/sh/sh4comn.h2
-rw-r--r--src/devices/cpu/sh/sh4fe.cpp26
-rw-r--r--src/devices/cpu/sh/sh4fe.h36
-rw-r--r--src/devices/cpu/sh/sh_fe.cpp577
-rw-r--r--src/devices/cpu/sh/sh_fe.h120
-rw-r--r--src/devices/cpu/sharc/sharc.cpp2
-rw-r--r--src/devices/cpu/sharc/sharc.h55
-rw-r--r--src/devices/cpu/sharc/sharcdrc.cpp297
-rw-r--r--src/devices/cpu/sharc/sharcfe.cpp987
-rw-r--r--src/devices/cpu/sharc/sharcfe.h223
-rw-r--r--src/devices/cpu/sharc/sharcinternal.ipp15
-rw-r--r--src/devices/cpu/unsp/unsp.cpp8
-rw-r--r--src/devices/cpu/unsp/unsp.h22
-rw-r--r--src/devices/cpu/unsp/unspdrc.cpp42
-rw-r--r--src/devices/cpu/unsp/unspfe.cpp214
-rw-r--r--src/devices/cpu/unsp/unspfe.h49
-rw-r--r--src/devices/sound/swp30.h2
56 files changed, 4234 insertions, 3220 deletions
diff --git a/scripts/src/cpu.lua b/scripts/src/cpu.lua
index 121ec87a8a6..9bf32fcaf66 100644
--- a/scripts/src/cpu.lua
+++ b/scripts/src/cpu.lua
@@ -32,8 +32,8 @@ if CPU_INCLUDE_DRC then
MAME_DIR .. "src/devices/cpu/drcbeut.h",
MAME_DIR .. "src/devices/cpu/drccache.cpp",
MAME_DIR .. "src/devices/cpu/drccache.h",
- MAME_DIR .. "src/devices/cpu/drcfe.cpp",
MAME_DIR .. "src/devices/cpu/drcfe.h",
+ MAME_DIR .. "src/devices/cpu/drcfe.ipp",
MAME_DIR .. "src/devices/cpu/drcuml.cpp",
MAME_DIR .. "src/devices/cpu/drcuml.h",
MAME_DIR .. "src/devices/cpu/uml.cpp",
@@ -879,11 +879,13 @@ end
if CPUS["SH"] then
files {
MAME_DIR .. "src/devices/cpu/sh/sh_fe.cpp",
+ MAME_DIR .. "src/devices/cpu/sh/sh_fe.h",
MAME_DIR .. "src/devices/cpu/sh/sh.cpp",
MAME_DIR .. "src/devices/cpu/sh/sh.h",
MAME_DIR .. "src/devices/cpu/sh/sh2.cpp",
MAME_DIR .. "src/devices/cpu/sh/sh2.h",
MAME_DIR .. "src/devices/cpu/sh/sh2fe.cpp",
+ MAME_DIR .. "src/devices/cpu/sh/sh2fe.h",
MAME_DIR .. "src/devices/cpu/sh/sh3comn.cpp",
MAME_DIR .. "src/devices/cpu/sh/sh3comn.h",
MAME_DIR .. "src/devices/cpu/sh/sh4.cpp",
@@ -893,6 +895,7 @@ if CPUS["SH"] then
MAME_DIR .. "src/devices/cpu/sh/sh4dmac.cpp",
MAME_DIR .. "src/devices/cpu/sh/sh4dmac.h",
MAME_DIR .. "src/devices/cpu/sh/sh4fe.cpp",
+ MAME_DIR .. "src/devices/cpu/sh/sh4fe.h",
MAME_DIR .. "src/devices/cpu/sh/sh4regs.h",
MAME_DIR .. "src/devices/cpu/sh/sh4tmu.cpp",
MAME_DIR .. "src/devices/cpu/sh/sh4tmu.h",
diff --git a/src/devices/cpu/drcfe.h b/src/devices/cpu/drcfe.h
index 8e2455c85d2..6822028428c 100644
--- a/src/devices/cpu/drcfe.h
+++ b/src/devices/cpu/drcfe.h
@@ -33,6 +33,9 @@
#pragma once
+#include <bitset>
+#include <vector>
+
//**************************************************************************
// CONSTANTS
@@ -42,125 +45,161 @@
constexpr offs_t BRANCH_TARGET_DYNAMIC = ~offs_t(0);
-// opcode branch flags
-constexpr u32 OPFLAG_IS_UNCONDITIONAL_BRANCH = 0x00000001; // instruction is unconditional branch
-constexpr u32 OPFLAG_IS_CONDITIONAL_BRANCH = 0x00000002; // instruction is conditional branch
-constexpr u32 OPFLAG_IS_BRANCH = (OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_IS_CONDITIONAL_BRANCH);
-constexpr u32 OPFLAG_IS_BRANCH_TARGET = 0x00000004; // instruction is the target of a branch
-constexpr u32 OPFLAG_IN_DELAY_SLOT = 0x00000008; // instruction is in the delay slot of a branch
-constexpr u32 OPFLAG_INTRABLOCK_BRANCH = 0x00000010; // instruction branches within the block
-
-// opcode exception flags
-constexpr u32 OPFLAG_CAN_TRIGGER_SW_INT = 0x00000020; // instruction can trigger a software interrupt
-constexpr u32 OPFLAG_CAN_EXPOSE_EXTERNAL_INT = 0x00000040; // instruction can expose an external interrupt
-constexpr u32 OPFLAG_CAN_CAUSE_EXCEPTION = 0x00000080; // instruction may generate exception
-constexpr u32 OPFLAG_WILL_CAUSE_EXCEPTION = 0x00000100; // instruction will generate exception
-constexpr u32 OPFLAG_PRIVILEGED = 0x00000200; // instruction is privileged
-
-// opcode virtual->physical translation flags
-constexpr u32 OPFLAG_VALIDATE_TLB = 0x00000400; // instruction must validate TLB before execution
-constexpr u32 OPFLAG_MODIFIES_TRANSLATION = 0x00000800; // instruction modifies the TLB
-constexpr u32 OPFLAG_COMPILER_PAGE_FAULT = 0x00001000; // compiler hit a page fault when parsing
-constexpr u32 OPFLAG_COMPILER_UNMAPPED = 0x00002000; // compiler hit unmapped memory when parsing
-
-// opcode flags
-constexpr u32 OPFLAG_INVALID_OPCODE = 0x00004000; // instruction is invalid
-constexpr u32 OPFLAG_VIRTUAL_NOOP = 0x00008000; // instruction is a virtual no-op
-
-// opcode sequence flow flags
-constexpr u32 OPFLAG_REDISPATCH = 0x00010000; // instruction must redispatch after completion
-constexpr u32 OPFLAG_RETURN_TO_START = 0x00020000; // instruction must jump back to the beginning after completion
-constexpr u32 OPFLAG_END_SEQUENCE = 0x00040000; // this is the last instruction in a sequence
-constexpr u32 OPFLAG_CAN_CHANGE_MODES = 0x00080000; // instruction can change modes
-
-// execution semantics
-constexpr u32 OPFLAG_READS_MEMORY = 0x00100000; // instruction reads memory
-constexpr u32 OPFLAG_WRITES_MEMORY = 0x00200000; // instruction writes memory
-
-
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// description of a given opcode
-struct opcode_desc
+template <typename Impl, size_t N>
+class opcode_desc_base
{
- opcode_desc *next() const { return m_next; }
+public:
+ using regmask = std::bitset<N>;
+
+ Impl *next() const { return m_next; }
+
+ void set_is_unconditional_branch() { m_flags.set(IS_UNCONDITIONAL_BRANCH); }
+ void set_is_conditional_branch() { m_flags.set(IS_CONDITIONAL_BRANCH); }
+ void set_is_branch_target() { m_flags.set(IS_BRANCH_TARGET); }
+ void set_in_delay_slot() { m_flags.set(IN_DELAY_SLOT); }
+ void set_intrablock_branch() { m_flags.set(INTRABLOCK_BRANCH); }
+ void set_can_cause_exception() { m_flags.set(CAN_CAUSE_EXCEPTION); }
+ void set_will_cause_exception() { m_flags.set(WILL_CAUSE_EXCEPTION); }
+ void set_validate_tlb() { m_flags.set(VALIDATE_TLB); }
+ void set_compiler_page_fault() { m_flags.set(COMPILER_PAGE_FAULT); }
+ void set_invalid_opcode() { m_flags.set(INVALID_OPCODE); }
+ void set_virtual_noop() { m_flags.set(VIRTUAL_NOOP); }
+ void set_redispatch() { m_flags.set(REDISPATCH); }
+ void set_return_to_start() { m_flags.set(RETURN_TO_START); }
+ void set_end_sequence() { m_flags.set(END_SEQUENCE); }
+
+ bool is_unconditional_branch() const { return m_flags[IS_UNCONDITIONAL_BRANCH]; }
+ bool is_conditional_branch() const { return m_flags[IS_CONDITIONAL_BRANCH]; }
+ bool is_branch() const { return is_unconditional_branch() || is_conditional_branch(); }
+ bool is_branch_target() const { return m_flags[IS_BRANCH_TARGET]; }
+ bool in_delay_slot() const { return m_flags[IN_DELAY_SLOT]; }
+ bool intrablock_branch() const { return m_flags[INTRABLOCK_BRANCH]; }
+ bool can_cause_exception() const { return m_flags[CAN_CAUSE_EXCEPTION]; }
+ bool will_cause_exception() const { return m_flags[WILL_CAUSE_EXCEPTION]; }
+ bool validate_tlb() const { return m_flags[VALIDATE_TLB]; }
+ bool compiler_page_fault() const { return m_flags[COMPILER_PAGE_FAULT]; }
+ bool invalid_opcode() const { return m_flags[INVALID_OPCODE]; }
+ bool virtual_noop() const { return m_flags[VIRTUAL_NOOP]; }
+ bool redispatch() const { return m_flags[REDISPATCH]; }
+ bool return_to_start() const { return m_flags[RETURN_TO_START]; }
+ bool end_sequence() const { return m_flags[END_SEQUENCE]; }
// links to other descriptions
- opcode_desc * m_next; // pointer to next description
- opcode_desc * branch; // pointer back to branch description for delay slots
- simple_list<opcode_desc> delay; // pointer to delay slot description
+ Impl * m_next; // pointer to next description
+ Impl * branch; // pointer back to branch description for delay slots
+ simple_list<Impl> delay; // pointer to delay slot description
// information about the current PC
offs_t pc; // PC of this opcode
- offs_t physpc; // physical PC of this opcode
offs_t targetpc; // target PC if we are a branch, or BRANCH_TARGET_DYNAMIC
- // copy of up to 16 bytes of opcode
- union
- {
- u8 b[16];
- u16 w[8];
- u32 l[4];
- u64 q[2];
- } opptr; // pointer to opcode memory
-
// information about this instruction's execution
u8 length; // length in bytes of this opcode
u8 delayslots; // number of delay slots (for branches)
u8 skipslots; // number of skip slots (for branches)
- u32 flags; // OPFLAG_* opcode flags
- u32 userflags; // core specific flags
- u32 userdata0; // core specific data
- u32 cycles; // number of cycles needed to execute
// register usage information
- u32 regin[4]; // input registers
- u32 regout[4]; // output registers
- u32 regreq[4]; // required output registers
+ regmask regin; // input registers
+ regmask regout; // output registers
+ regmask regreq; // required output registers
+
+protected:
+ enum
+ {
+ // opcode branch flags
+ IS_UNCONDITIONAL_BRANCH = 0, // instruction is unconditional branch
+ IS_CONDITIONAL_BRANCH, // instruction is conditional branch
+ IS_BRANCH_TARGET, // instruction is the target of a branch
+ IN_DELAY_SLOT, // instruction is in the delay slot of a branch
+ INTRABLOCK_BRANCH, // instruction branches within the block
+
+ // opcode exception flags
+ CAN_CAUSE_EXCEPTION, // instruction may generate exception
+ WILL_CAUSE_EXCEPTION, // instruction will generate exception
+
+ // opcode virtual->physical translation flags
+ VALIDATE_TLB, // instruction must validate TLB before execution
+ COMPILER_PAGE_FAULT, // compiler hit a page fault when parsing
+
+ // opcode flags
+ INVALID_OPCODE, // instruction is invalid
+ VIRTUAL_NOOP, // instruction is a virtual no-op
+
+ // opcode sequence flow flags
+ REDISPATCH, // instruction must redispatch after completion
+ RETURN_TO_START, // instruction must jump back to the beginning after completion
+ END_SEQUENCE, // this is the last instruction in a sequence
+
+ FLAG_COUNT
+ };
+
+ void reset(offs_t curpc, bool in_delay_slot)
+ {
+ m_next = nullptr;
+ branch = nullptr;
+ delay.reset();
+ pc = curpc;
+ targetpc = BRANCH_TARGET_DYNAMIC;
+ length = 0;
+ delayslots = 0;
+ skipslots = 0;
+ regin.reset();
+ regout.reset();
+ regreq.reset();
+ m_flags.reset();
+
+ // set the delay slot flag
+ if (in_delay_slot)
+ set_in_delay_slot();
+ }
+
+ std::bitset<FLAG_COUNT> m_flags;
};
// DRC frontend state
-class drc_frontend
+template <typename Desc>
+class drc_frontend_base
{
public:
// construction/destruction
- drc_frontend(device_t &cpu, u32 window_start, u32 window_end, u32 max_sequence);
- virtual ~drc_frontend();
+ drc_frontend_base(offs_t pageshift, u32 window_start, u32 window_end, u32 max_sequence);
+ ~drc_frontend_base();
- // describe a block
- opcode_desc const *describe_code(offs_t startpc);
// get last opcode of block
- opcode_desc const *get_last() { return m_desc_live_list.last(); }
+ Desc const *get_last() { return m_desc_live_list.last(); }
protected:
- // required overrides
- virtual bool describe(opcode_desc &desc, opcode_desc const *prev) = 0;
+ // describe a block
+ template <typename T>
+ Desc const *do_describe_code(T && describe, offs_t startpc);
private:
// internal helpers
- opcode_desc *describe_one(offs_t curpc, opcode_desc const *prevdesc, bool in_delay_slot = false);
- void build_sequence(int start, int end, u32 endflag);
- void accumulate_required_backwards(opcode_desc &desc, u32 *reqmask);
+ template <typename T>
+ Desc *describe_one(T &&describe, offs_t curpc, Desc const *prevdesc, bool in_delay_slot = false);
+ void build_sequence(int start, int end, bool redispatch);
+ void accumulate_required_backwards(Desc &desc, typename Desc::regmask &reqmask);
void release_descriptions();
// configuration parameters
- u32 m_window_start; // code window start offset = startpc - window_start
- u32 m_window_end; // code window end offset = startpc + window_end
- u32 m_max_sequence; // maximum instructions to include in a sequence
+ u32 const m_window_start; // code window start offset = startpc - window_start
+ u32 const m_window_end; // code window end offset = startpc + window_end
+ u32 const m_max_sequence; // maximum instructions to include in a sequence
// CPU parameters
- cpu_device & m_cpudevice; // CPU device object
- address_space & m_program; // program address space for this CPU
- offs_t m_pageshift; // shift to convert address to a page index
+ offs_t const m_pageshift; // shift to convert address to a page index
// opcode descriptor arrays
- simple_list<opcode_desc> m_desc_live_list; // list of live descriptions
- fixed_allocator<opcode_desc> m_desc_allocator; // fixed allocator for descriptions
- std::vector<opcode_desc *> m_desc_array; // array of descriptions in PC order
+ simple_list<Desc> m_desc_live_list; // list of live descriptions
+ fixed_allocator<Desc> m_desc_allocator; // fixed allocator for descriptions
+ std::vector<Desc *> m_desc_array; // array of descriptions in PC order
};
#endif // MAME_CPU_DRCFE_H
diff --git a/src/devices/cpu/drcfe.cpp b/src/devices/cpu/drcfe.ipp
index a13f23f39f4..681cb85c50a 100644
--- a/src/devices/cpu/drcfe.cpp
+++ b/src/devices/cpu/drcfe.ipp
@@ -2,7 +2,7 @@
// copyright-holders:Aaron Giles
/***************************************************************************
- drcfe.c
+ drcfe.ipp
Generic dynamic recompiler frontend structures and utilities.
@@ -14,34 +14,14 @@
intrablock branches
***************************************************************************/
+#ifndef MAME_CPU_DRCFE_IPP
+#define MAME_CPU_DRCFE_IPP
-#include "emu.h"
-#include "drcfe.h"
-
-
-namespace {
-
-//**************************************************************************
-// CONSTANTS
-//**************************************************************************
-
-constexpr u32 MAX_STACK_DEPTH = 100;
-
-
+#pragma once
-//**************************************************************************
-// TYPE DEFINITIONS
-//**************************************************************************
-
-// an entry that maps branches for our code walking
-struct pc_stack_entry
-{
- offs_t targetpc;
- offs_t srcpc;
-};
-
-} // anonymous namespace
+#include "drcfe.h"
+#include <algorithm>
//**************************************************************************
@@ -49,26 +29,26 @@ struct pc_stack_entry
//**************************************************************************
//-------------------------------------------------
-// drc_frontend - constructor
+// drc_frontend_base - constructor
//-------------------------------------------------
-drc_frontend::drc_frontend(device_t &cpu, u32 window_start, u32 window_end, u32 max_sequence)
+template <typename Desc>
+drc_frontend_base<Desc>::drc_frontend_base(offs_t pageshift, u32 window_start, u32 window_end, u32 max_sequence)
: m_window_start(window_start)
, m_window_end(window_end)
, m_max_sequence(max_sequence)
- , m_cpudevice(downcast<cpu_device &>(cpu))
- , m_program(m_cpudevice.space(AS_PROGRAM))
- , m_pageshift(m_cpudevice.space_config(AS_PROGRAM)->page_shift())
+ , m_pageshift(pageshift)
, m_desc_array(window_end + window_start + 2, nullptr)
{
}
//-------------------------------------------------
-// ~drc_frontend - destructor
+// ~drc_frontend_base - destructor
//-------------------------------------------------
-drc_frontend::~drc_frontend()
+template <typename Desc>
+drc_frontend_base<Desc>::~drc_frontend_base()
{
// release any descriptions we've accumulated
release_descriptions();
@@ -81,8 +61,19 @@ drc_frontend::~drc_frontend()
// relative to the specified startpc
//-------------------------------------------------
-const opcode_desc *drc_frontend::describe_code(offs_t startpc)
+template <typename Desc>
+template <typename T>
+const Desc *drc_frontend_base<Desc>::do_describe_code(T &&describe, offs_t startpc)
{
+ constexpr u32 MAX_STACK_DEPTH = 100;
+
+ // an entry that maps branches for our code walking
+ struct pc_stack_entry
+ {
+ offs_t targetpc;
+ offs_t srcpc;
+ };
+
// release any descriptions we've accumulated
release_descriptions();
@@ -100,14 +91,17 @@ const opcode_desc *drc_frontend::describe_code(offs_t startpc)
{
// if we've already hit this PC, just mark it a branch target and continue
pc_stack_entry *const curstack = --pcstackptr;
- opcode_desc *curdesc = m_desc_array[curstack->targetpc - minpc];
+ Desc *curdesc = m_desc_array[curstack->targetpc - minpc];
if (curdesc != nullptr)
{
- curdesc->flags |= OPFLAG_IS_BRANCH_TARGET;
+ curdesc->set_is_branch_target();
// if the branch crosses a page boundary, mark the target as needing to revalidate
if (m_pageshift != 0 && ((curstack->srcpc ^ curdesc->pc) >> m_pageshift) != 0)
- curdesc->flags |= OPFLAG_VALIDATE_TLB | OPFLAG_CAN_CAUSE_EXCEPTION;
+ {
+ curdesc->set_validate_tlb();
+ curdesc->set_can_cause_exception();
+ }
// continue processing
continue;
@@ -117,39 +111,42 @@ const opcode_desc *drc_frontend::describe_code(offs_t startpc)
for (offs_t curpc = curstack->targetpc; curpc >= minpc && curpc < maxpc && m_desc_array[curpc - minpc] == nullptr; curpc += m_desc_array[curpc - minpc]->length)
{
// allocate a new description and describe this instruction
- m_desc_array[curpc - minpc] = curdesc = describe_one(curpc, curdesc);
+ m_desc_array[curpc - minpc] = curdesc = describe_one(describe, curpc, curdesc);
// first instruction in a sequence is always a branch target
if (curpc == curstack->targetpc)
- curdesc->flags |= OPFLAG_IS_BRANCH_TARGET;
+ curdesc->set_is_branch_target();
// stop if we hit a page fault
- if (curdesc->flags & OPFLAG_COMPILER_PAGE_FAULT)
+ if (curdesc->compiler_page_fault())
break;
// if we are the first instruction in the whole window, we must validate the TLB
if (curpc == startpc && m_pageshift != 0)
- curdesc->flags |= OPFLAG_VALIDATE_TLB | OPFLAG_CAN_CAUSE_EXCEPTION;
+ {
+ curdesc->set_validate_tlb();
+ curdesc->set_can_cause_exception();
+ }
// if we are a branch within the block range, add the branch target to our stack
- if ((curdesc->flags & OPFLAG_IS_BRANCH) && curdesc->targetpc >= minpc && curdesc->targetpc < maxpc && pcstackptr < &pcstack[MAX_STACK_DEPTH])
+ if (curdesc->is_branch() && (curdesc->targetpc >= minpc) && (curdesc->targetpc < maxpc) && (pcstackptr < &pcstack[MAX_STACK_DEPTH]))
{
- curdesc->flags |= OPFLAG_INTRABLOCK_BRANCH;
+ curdesc->set_intrablock_branch();
pcstackptr->srcpc = curdesc->pc;
pcstackptr->targetpc = curdesc->targetpc;
pcstackptr++;
}
// if we're done, we're done
- if (curdesc->flags & OPFLAG_END_SEQUENCE)
+ if (curdesc->end_sequence())
break;
}
}
// now build the list of descriptions in order
// first from startpc -> maxpc, then from minpc -> startpc
- build_sequence(startpc - minpc, maxpc - minpc, OPFLAG_REDISPATCH);
- build_sequence(minpc - minpc, startpc - minpc, OPFLAG_RETURN_TO_START);
+ build_sequence(startpc - minpc, maxpc - minpc, true);
+ build_sequence(minpc - minpc, startpc - minpc, false);
return m_desc_live_list.first();
}
@@ -160,62 +157,55 @@ const opcode_desc *drc_frontend::describe_code(offs_t startpc)
// slots of branches as well
//-------------------------------------------------
-opcode_desc *drc_frontend::describe_one(offs_t curpc, opcode_desc const *prevdesc, bool in_delay_slot)
+template <typename Desc>
+template <typename T>
+Desc *drc_frontend_base<Desc>::describe_one(T &&describe, offs_t curpc, Desc const *prevdesc, bool in_delay_slot)
{
// initialize the description
- opcode_desc *const desc = m_desc_allocator.alloc();
- desc->m_next = nullptr;
- desc->branch = nullptr;
- desc->delay.reset();
- desc->pc = curpc;
- desc->physpc = curpc;
- desc->targetpc = BRANCH_TARGET_DYNAMIC;
- memset(&desc->opptr, 0x00, sizeof(desc->opptr));
- desc->length = 0;
- desc->delayslots = 0;
- desc->skipslots = 0;
- // set the delay slot flag
- desc->flags = in_delay_slot ? OPFLAG_IN_DELAY_SLOT : 0;
- desc->userflags = 0;
- desc->userdata0 = 0;
- desc->cycles = 0;
- memset(desc->regin, 0x00, sizeof(desc->regin));
- memset(desc->regout, 0x00, sizeof(desc->regout));
- memset(desc->regreq, 0x00, sizeof(desc->regreq));
+ Desc *const desc = m_desc_allocator.alloc();
+ desc->reset(curpc, in_delay_slot);
// call the callback to describe an instruction
if (!describe(*desc, prevdesc))
{
- desc->flags |= OPFLAG_WILL_CAUSE_EXCEPTION | OPFLAG_INVALID_OPCODE;
+ desc->set_will_cause_exception();
+ desc->set_invalid_opcode();
return desc;
}
// validate the TLB if we are exactly at the start of a page, or if we cross a page boundary
if (m_pageshift != 0 && (((curpc - 1) ^ (curpc + desc->length - 1)) >> m_pageshift) != 0)
- desc->flags |= OPFLAG_VALIDATE_TLB | OPFLAG_CAN_CAUSE_EXCEPTION;
+ {
+ desc->set_validate_tlb();
+ desc->set_can_cause_exception();
+ }
// validate stuff
- assert(desc->length > 0 || (desc->flags & OPFLAG_VIRTUAL_NOOP) != 0);
+ assert((desc->length > 0) || desc->virtual_noop());
// if we are a branch with delay slots, recursively walk those
- if (desc->flags & OPFLAG_IS_BRANCH)
+ if (desc->is_branch())
{
// iterate over slots and describe them
offs_t delaypc = curpc + desc->length;
// If this is a delay slot it is the true branch fork and the pc should be the previous branch target
- if (desc->flags & OPFLAG_IN_DELAY_SLOT) {
- if (prevdesc->targetpc != BRANCH_TARGET_DYNAMIC) {
+ if (desc->in_delay_slot())
+ {
+ if (prevdesc->targetpc != BRANCH_TARGET_DYNAMIC)
+ {
delaypc = prevdesc->targetpc;
- //printf("drc_frontend::describe_one Branch in delay slot. curpc=%08X delaypc=%08X\n", curpc, delaypc);
- } else {
- //printf("drc_frontend::describe_one Warning! Branch in delay slot of dynamic target. curpc=%08X\n", curpc);
+ //printf("drc_frontend_base::describe_one Branch in delay slot. curpc=%08X delaypc=%08X\n", curpc, delaypc);
+ }
+ else
+ {
+ //printf("drc_frontend_base::describe_one Warning! Branch in delay slot of dynamic target. curpc=%08X\n", curpc);
}
}
- opcode_desc *prev = desc;
+ Desc *prev = desc;
for (u8 slotnum = 0; slotnum < desc->delayslots; slotnum++)
{
// recursively describe the next instruction
- opcode_desc *delaydesc = describe_one(delaypc, prev, true);
+ Desc *delaydesc = describe_one(describe, delaypc, prev, true);
if (delaydesc == nullptr)
break;
desc->delay.append(*delaydesc);
@@ -225,7 +215,7 @@ opcode_desc *drc_frontend::describe_one(offs_t curpc, opcode_desc const *prevdes
delaydesc->branch = desc;
// stop if we hit a page fault
- if (delaydesc->flags & OPFLAG_COMPILER_PAGE_FAULT)
+ if (delaydesc->compiler_page_fault())
break;
// otherwise, advance
@@ -241,19 +231,21 @@ opcode_desc *drc_frontend::describe_one(offs_t curpc, opcode_desc const *prevdes
// of instructions
//-------------------------------------------------
-void drc_frontend::build_sequence(int start, int end, u32 endflag)
+template <typename Desc>
+void drc_frontend_base<Desc>::build_sequence(int start, int end, bool redispatch)
{
// iterate in order from start to end, picking up all non-NULL instructions
int consecutive = 0;
int seqstart = -1;
int skipsleft = 0;
for (int descnum = start; descnum < end; descnum++)
+ {
if (m_desc_array[descnum] != nullptr)
{
// determine the next instruction, taking skips into account
- opcode_desc *curdesc = m_desc_array[descnum];
+ Desc *curdesc = m_desc_array[descnum];
int nextdescnum = descnum + curdesc->length;
- opcode_desc *nextdesc = (nextdescnum < end) ? m_desc_array[nextdescnum] : nullptr;
+ Desc *nextdesc = (nextdescnum < end) ? m_desc_array[nextdescnum] : nullptr;
for (u8 skipnum = 0; skipnum < curdesc->skipslots && nextdesc != nullptr; skipnum++)
{
nextdescnum = nextdescnum + nextdesc->length;
@@ -264,16 +256,19 @@ void drc_frontend::build_sequence(int start, int end, u32 endflag)
if (seqstart == -1 && skipsleft == 0)
{
// tag all start-of-sequence instructions as needing TLB verification
- curdesc->flags |= OPFLAG_VALIDATE_TLB | OPFLAG_CAN_CAUSE_EXCEPTION;
+ curdesc->set_validate_tlb();
+ curdesc->set_can_cause_exception();
seqstart = descnum;
}
// if we are the last instruction, indicate end-of-sequence and redispatch
if (nextdesc == nullptr)
{
- curdesc->flags |= OPFLAG_END_SEQUENCE;
- if (endflag != OPFLAG_RETURN_TO_START || nextdescnum == end)
- curdesc->flags |= endflag;
+ curdesc->set_end_sequence();
+ if (redispatch)
+ curdesc->set_redispatch();
+ else if (nextdescnum == end)
+ curdesc->set_return_to_start();
}
// otherwise, do some analysis based on the next instruction
@@ -281,7 +276,7 @@ void drc_frontend::build_sequence(int start, int end, u32 endflag)
{
// if there are instructions between us and the next instruction, we must end our sequence here
int scandescnum;
- opcode_desc *scandesc = nullptr;
+ Desc *scandesc = nullptr;
for (scandescnum = descnum + 1; scandescnum < end; scandescnum++)
{
scandesc = m_desc_array[scandescnum];
@@ -289,28 +284,33 @@ void drc_frontend::build_sequence(int start, int end, u32 endflag)
break;
}
if (scandesc != nextdesc)
- curdesc->flags |= OPFLAG_END_SEQUENCE;
+ curdesc->set_end_sequence();
// if the next instruction is a branch target, mark this instruction as end of sequence
- if (nextdesc->flags & OPFLAG_IS_BRANCH_TARGET)
- curdesc->flags |= OPFLAG_END_SEQUENCE;
+ if (nextdesc->is_branch_target())
+ curdesc->set_end_sequence();
}
// if we exceed the maximum consecutive count, cut off the sequence
if (++consecutive >= m_max_sequence)
- curdesc->flags |= OPFLAG_END_SEQUENCE;
- if (curdesc->flags & OPFLAG_END_SEQUENCE)
+ curdesc->set_end_sequence();
+ if (curdesc->end_sequence())
consecutive = 0;
// if this is the end of a sequence, work backwards
- if (curdesc->flags & OPFLAG_END_SEQUENCE)
+ if (curdesc->end_sequence())
{
// figure out which registers we *must* generate, assuming at the end all must be
- u32 reqmask[4] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff };
+ typename Desc::regmask reqmask;
+ reqmask.set();
if (seqstart != -1)
+ {
for (int backdesc = descnum; backdesc != seqstart - 1; backdesc--)
+ {
if (m_desc_array[backdesc] != nullptr)
accumulate_required_backwards(*m_desc_array[backdesc], reqmask);
+ }
+ }
// reset the register states
seqstart = -1;
@@ -318,7 +318,7 @@ void drc_frontend::build_sequence(int start, int end, u32 endflag)
// if we have instructions remaining to be skipped, and this instruction is a branch target
// belay the skip order
- if (skipsleft > 0 && (curdesc->flags & OPFLAG_IS_BRANCH_TARGET))
+ if ((skipsleft > 0) && curdesc->is_branch_target())
skipsleft = 0;
// if we're not getting skipped, add us to the end of the list and clear our array slot
@@ -334,9 +334,10 @@ void drc_frontend::build_sequence(int start, int end, u32 endflag)
else if (skipsleft > 0)
skipsleft--;
}
+ }
// zap the array
- memset(&m_desc_array[start], 0, (end - start) * sizeof(m_desc_array[0]));
+ std::fill_n(&m_desc_array[start], end - start, nullptr);
}
@@ -346,33 +347,25 @@ void drc_frontend::build_sequence(int start, int end, u32 endflag)
// walking in a backwards direction
//-------------------------------------------------
-void drc_frontend::accumulate_required_backwards(opcode_desc &desc, u32 *reqmask)
+template <typename Desc>
+void drc_frontend_base<Desc>::accumulate_required_backwards(Desc &desc, typename Desc::regmask &reqmask)
{
// recursively handle delay slots
if (desc.delay.first() != nullptr)
accumulate_required_backwards(*desc.delay.first(), reqmask);
// if this is a branch, we have to reset our requests
- if (desc.flags & OPFLAG_IS_BRANCH)
- reqmask[0] = reqmask[1] = reqmask[2] = reqmask[3] = 0xffffffff;
+ if (desc.is_branch())
+ reqmask = reqmask = reqmask = reqmask.set();
// determine the required registers
- desc.regreq[0] = desc.regout[0] & reqmask[0];
- desc.regreq[1] = desc.regout[1] & reqmask[1];
- desc.regreq[2] = desc.regout[2] & reqmask[2];
- desc.regreq[3] = desc.regout[3] & reqmask[3];
+ desc.regreq = desc.regout & reqmask;
// any registers modified by this instruction aren't required upstream until referenced
- reqmask[0] &= ~desc.regout[0];
- reqmask[1] &= ~desc.regout[1];
- reqmask[2] &= ~desc.regout[2];
- reqmask[3] &= ~desc.regout[3];
+ reqmask &= ~desc.regout;
// any registers required by this instruction now get marked required
- reqmask[0] |= desc.regin[0];
- reqmask[1] |= desc.regin[1];
- reqmask[2] |= desc.regin[2];
- reqmask[3] |= desc.regin[3];
+ reqmask |= desc.regin;
}
@@ -382,12 +375,15 @@ void drc_frontend::accumulate_required_backwards(opcode_desc &desc, u32 *reqmask
// free list
//------------------------------------------------
-void drc_frontend::release_descriptions()
+template <typename Desc>
+void drc_frontend_base<Desc>::release_descriptions()
{
// release all delay slots first
- for (opcode_desc *curdesc = m_desc_live_list.first(); curdesc != nullptr; curdesc = curdesc->next())
+ for (Desc *curdesc = m_desc_live_list.first(); curdesc != nullptr; curdesc = curdesc->next())
m_desc_allocator.reclaim_all(curdesc->delay);
// reclaim all the descriptors
m_desc_allocator.reclaim_all(m_desc_live_list);
}
+
+#endif // MAME_CPU_DRCFE_IPP
diff --git a/src/devices/cpu/dsp16/dsp16.h b/src/devices/cpu/dsp16/dsp16.h
index f969f14e851..3e4b6f941fc 100644
--- a/src/devices/cpu/dsp16/dsp16.h
+++ b/src/devices/cpu/dsp16/dsp16.h
@@ -17,6 +17,7 @@
#include <memory>
#include <utility>
+
class dsp16_device_base : public cpu_device, protected dsp16_disassembler::cpu
{
public:
@@ -173,6 +174,7 @@ private:
// recompiler helpers
class core_state;
+ class opcode_desc;
class frontend;
class recompiler;
struct core_destructer { void operator()(core_state *obj) const noexcept; };
diff --git a/src/devices/cpu/dsp16/dsp16fe.cpp b/src/devices/cpu/dsp16/dsp16fe.cpp
index 406cf205433..4c10ed14a49 100644
--- a/src/devices/cpu/dsp16/dsp16fe.cpp
+++ b/src/devices/cpu/dsp16/dsp16fe.cpp
@@ -9,28 +9,41 @@
#include "emu.h"
#include "dsp16fe.h"
+#include "cpu/drcfe.ipp"
+
/***********************************************************************
construction/destruction
***********************************************************************/
dsp16_device_base::frontend::frontend(dsp16_device_base &host, u32 window_start, u32 window_end, u32 max_sequence)
- : drc_frontend(host, window_start, window_end, max_sequence)
+ : drc_frontend_base(host.space_config(AS_PROGRAM)->page_shift(), window_start, window_end, max_sequence)
, m_host(host)
{
}
+dsp16_device_base::frontend::~frontend()
+{
+}
+
/***********************************************************************
drc_frontend implementation
***********************************************************************/
+dsp16_device_base::opcode_desc const *dsp16_device_base::frontend::describe_code(offs_t startpc)
+{
+ return do_describe_code(
+ [this] (opcode_desc &desc, opcode_desc const *prev) { return describe(desc, prev); },
+ startpc);
+}
+
bool dsp16_device_base::frontend::describe(opcode_desc &desc, opcode_desc const *prev)
{
// most instructions are one word long and run in one machine cycle
desc.length = 1U;
desc.cycles = 1U;
- u16 const op(m_host.m_pcache.read_word(desc.physpc));
+ u16 const op(m_host.m_pcache.read_word(desc.pc));
switch (op >> 11)
{
case 0x00: // goto JA
@@ -38,8 +51,9 @@ bool dsp16_device_base::frontend::describe(opcode_desc &desc, opcode_desc const
case 0x10: // call JA
case 0x11:
desc.cycles = 2U;
- desc.targetpc = (desc.physpc & XAAU_I_EXT) | (op_ja(op) & XAAU_I_MASK);
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH;
+ desc.targetpc = (desc.pc & XAAU_I_EXT) | (op_ja(op) & XAAU_I_MASK);
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
if (BIT(op, 15))
flag_output_reg(desc, REG_BIT_XAAU_PR);
return true;
@@ -79,7 +93,7 @@ bool dsp16_device_base::frontend::describe(opcode_desc &desc, opcode_desc const
case 0x08: // aT = R
desc.cycles = 2U;
if (op & 0x000fU) // reserved field?
- desc.flags |= OPFLAG_INVALID_OPCODE;
+ desc.set_invalid_opcode();
flag_output_reg(desc, op_d(op) ? REG_BIT_DAU_A0 : REG_BIT_DAU_A1, REG_BIT_DAU_PSW);
describe_r(desc, op, true, false);
return true;
@@ -88,7 +102,7 @@ bool dsp16_device_base::frontend::describe(opcode_desc &desc, opcode_desc const
case 0x0b: // R = a1
desc.cycles = 2U;
if (op & 0x000fU) // reserved field?
- desc.flags |= OPFLAG_INVALID_OPCODE;
+ desc.set_invalid_opcode();
flag_input_reg(desc, BIT(op, 12) ? REG_BIT_DAU_A1 : REG_BIT_DAU_A0, REG_BIT_DAU_AUC);
describe_r(desc, op, false, true);
return true;
@@ -97,14 +111,14 @@ bool dsp16_device_base::frontend::describe(opcode_desc &desc, opcode_desc const
desc.length = 2U;
desc.cycles = 2U;
if (op & 0x000fU) // reserved field?
- desc.flags |= OPFLAG_INVALID_OPCODE;
+ desc.set_invalid_opcode();
describe_r(desc, op, false, true);
return true;
case 0x0c: // Y = R
desc.cycles = 2U;
if (op & 0x0400U) // reserved field?
- desc.flags |= OPFLAG_INVALID_OPCODE;
+ desc.set_invalid_opcode();
describe_r(desc, op, true, false);
describe_y(desc, op, false, true);
return true;
@@ -124,7 +138,7 @@ bool dsp16_device_base::frontend::describe(opcode_desc &desc, opcode_desc const
case 0x0f: // R = Y
desc.cycles = 2U;
if (op & 0x0400U) // reserved field?
- desc.flags |= OPFLAG_INVALID_OPCODE;
+ desc.set_invalid_opcode();
describe_r(desc, op, false, true);
describe_y(desc, op, true, false);
return true;
@@ -175,7 +189,7 @@ bool dsp16_device_base::frontend::describe(opcode_desc &desc, opcode_desc const
case 0x1b: // F1 ; y = a1 ; x = *pt++[i]
desc.cycles = 2U;
if (op & 0x000fU)
- desc.flags |= OPFLAG_INVALID_OPCODE;
+ desc.set_invalid_opcode();
flag_input_reg(desc, BIT(op, 12) ? REG_BIT_DAU_A1 : REG_BIT_DAU_A0, REG_BIT_DAU_AUC);
flag_output_reg(desc, REG_BIT_DAU_Y);
describe_f1(desc, op);
@@ -184,7 +198,7 @@ bool dsp16_device_base::frontend::describe(opcode_desc &desc, opcode_desc const
case 0x1a: // if CON # icall
if (op & 0x03e0U) // reserved field?
- desc.flags |= OPFLAG_INVALID_OPCODE;
+ desc.set_invalid_opcode();
if (BIT(op, 10))
return describe_icall(desc, op);
else
@@ -200,7 +214,7 @@ bool dsp16_device_base::frontend::describe(opcode_desc &desc, opcode_desc const
return true;
case 0x1e: // Reserved
- desc.flags |= OPFLAG_INVALID_OPCODE;
+ desc.set_invalid_opcode();
return true;
case 0x1f: // F1 ; y = Y ; x = *pt++[i]
@@ -221,7 +235,7 @@ bool dsp16_device_base::frontend::describe(opcode_desc &desc, opcode_desc const
u16 dsp16_device_base::frontend::read_op(opcode_desc const &desc, u16 offset)
{
- return m_host.m_pcache.read_word((desc.physpc & XAAU_I_EXT) | ((desc.physpc + offset) & XAAU_I_MASK));
+ return m_host.m_pcache.read_word((desc.pc & XAAU_I_EXT) | ((desc.pc + offset) & XAAU_I_MASK));
}
/***********************************************************************
@@ -232,16 +246,17 @@ bool dsp16_device_base::frontend::describe_goto_b(opcode_desc &desc, u16 op)
{
desc.cycles = 2U;
if (op & 0x00ffU)
- desc.flags |= OPFLAG_INVALID_OPCODE;
+ desc.set_invalid_opcode();
desc.targetpc = BRANCH_TARGET_DYNAMIC;
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH;
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
switch (op_b(op))
{
case 0x0: // return
flag_input_reg(desc, REG_BIT_XAAU_PR);
break;
case 0x1: // ireturn
- desc.flags |= OPFLAG_CAN_CHANGE_MODES; // FIXME: is this flag useful for a switch in/out of interrupt service mode?
+ desc.set_can_change_modes(); // FIXME: is this flag useful for a switch in/out of interrupt service mode?
flag_input_reg(desc, REG_BIT_XAAU_PI);
break;
case 0x2: // goto pt
@@ -255,7 +270,7 @@ bool dsp16_device_base::frontend::describe_goto_b(opcode_desc &desc, u16 op)
case 0x5:
case 0x6:
case 0x7:
- desc.flags |= OPFLAG_INVALID_OPCODE;
+ desc.set_invalid_opcode();
break;
}
return true;
@@ -276,16 +291,17 @@ bool dsp16_device_base::frontend::describe_if_con(opcode_desc &desc, u16 op)
switch (op_con(op))
{
case 0xe: // true
- desc.targetpc = (desc.physpc & XAAU_I_EXT) | (op_ja(next) & XAAU_I_MASK);
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH;
+ desc.targetpc = (desc.pc & XAAU_I_EXT) | (op_ja(next) & XAAU_I_MASK);
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
if (BIT(next, 15))
flag_output_reg(desc, REG_BIT_XAAU_PR);
break;
case 0xf: // false
break;
default:
- desc.targetpc = (desc.physpc & XAAU_I_EXT) | (op_ja(next) & XAAU_I_MASK);
- desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+ desc.targetpc = (desc.pc & XAAU_I_EXT) | (op_ja(next) & XAAU_I_MASK);
+ desc.set_is_conditional_branch();
if (BIT(next, 15))
flag_output_reg(desc, REG_BIT_XAAU_PR);
}
@@ -306,13 +322,15 @@ bool dsp16_device_base::frontend::describe_if_con(opcode_desc &desc, u16 op)
case 0x5:
case 0x6:
case 0x7:
- desc.flags |= OPFLAG_INVALID_OPCODE;
+ desc.set_invalid_opcode();
break;
}
if (op_b(next) == 0x1) // can't predicate ireturn?
{
desc.targetpc = BRANCH_TARGET_DYNAMIC;
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_CAN_CHANGE_MODES; // FIXME: confirm appropriate flags
+ desc.set_is_unconditional_branch(); // FIXME: confirm appropriate flags
+ desc.set_end_sequence();
+ desc.set_can_change_modes();
flag_input_reg(desc, REG_BIT_XAAU_PI);
}
else
@@ -321,7 +339,8 @@ bool dsp16_device_base::frontend::describe_if_con(opcode_desc &desc, u16 op)
{
case 0xe: // true
desc.targetpc = BRANCH_TARGET_DYNAMIC;
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH;
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
switch (op_b(next))
{
case 0x0: // return
@@ -340,7 +359,7 @@ bool dsp16_device_base::frontend::describe_if_con(opcode_desc &desc, u16 op)
break;
default:
desc.targetpc = BRANCH_TARGET_DYNAMIC;
- desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+ desc.set_is_conditional_branch();
switch (op_b(next))
{
case 0x0: // return
@@ -359,7 +378,7 @@ bool dsp16_device_base::frontend::describe_if_con(opcode_desc &desc, u16 op)
break;
default:
- desc.flags |= OPFLAG_INVALID_OPCODE; // can't predicate things that aren't branches?
+ desc.set_invalid_opcode(); // can't predicate things that aren't branches?
}
describe_con(desc, op, true);
return true;
@@ -369,18 +388,22 @@ bool dsp16_device_base::frontend::describe_icall(opcode_desc &desc, u16 op)
{
desc.cycles = 3U;
if (0x000eU != op_con(op)) // CON must be true for icall?
- desc.flags |= OPFLAG_INVALID_OPCODE;
+ desc.set_invalid_opcode();
switch (op_con(op))
{
case 0xe: // true
desc.targetpc = 0x0002U;
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_CAN_CHANGE_MODES; // FIXME: confirm appropriate flags
+ desc.set_is_unconditional_branch(); // FIXME: confirm appropriate flags
+ desc.set_end_sequence();
+ desc.set_can_change_modes();
break;
case 0xf: // false
break;
default:
desc.targetpc = 0x0002U;
- desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH | OPFLAG_CAN_CHANGE_MODES; // FIXME: confirm appropriate flags
+ desc.set_is_unconditional_branch(); // FIXME: confirm appropriate flags
+ desc.set_end_sequence();
+ desc.set_can_change_modes();
}
describe_con(desc, op, true);
return true;
@@ -390,7 +413,7 @@ bool dsp16_device_base::frontend::describe_do(opcode_desc &desc, u16 op)
{
u16 const ni(op_ni(op)), k(op_k(op));
if (2U > k) // p3-25: "The iteration count can be between 2 and 127, inclusive"
- desc.flags |= OPFLAG_INVALID_OPCODE;
+ desc.set_invalid_opcode();
desc.length = ni + 1;
u32 cycles(0U), romcycles(0U), cachecycles(0U);
for (u16 i = 0; i < ni; ++i)
@@ -436,7 +459,7 @@ bool dsp16_device_base::frontend::describe_do(opcode_desc &desc, u16 op)
case 0x08: // aT = R
romcycles = cachecycles = 2U;
if (op & 0x000fU) // reserved field?
- desc.flags |= OPFLAG_INVALID_OPCODE;
+ desc.set_invalid_opcode();
flag_output_reg(desc, op_d(op) ? REG_BIT_DAU_A0 : REG_BIT_DAU_A1, REG_BIT_DAU_PSW);
describe_r(desc, op, true, false);
break;
@@ -445,7 +468,7 @@ bool dsp16_device_base::frontend::describe_do(opcode_desc &desc, u16 op)
case 0x0b: // R = a1
romcycles = cachecycles = 2U;
if (op & 0x000fU) // reserved field?
- desc.flags |= OPFLAG_INVALID_OPCODE;
+ desc.set_invalid_opcode();
flag_input_reg(desc, BIT(op, 12) ? REG_BIT_DAU_A1 : REG_BIT_DAU_A0, REG_BIT_DAU_AUC);
describe_r(desc, op, false, true);
break;
@@ -453,7 +476,7 @@ bool dsp16_device_base::frontend::describe_do(opcode_desc &desc, u16 op)
case 0x0c: // Y = R
romcycles = cachecycles = 2U;
if (op & 0x0400U) // reserved field?
- desc.flags |= OPFLAG_INVALID_OPCODE;
+ desc.set_invalid_opcode();
describe_r(desc, op, true, false);
describe_y(desc, op, false, true);
break;
@@ -467,7 +490,7 @@ bool dsp16_device_base::frontend::describe_do(opcode_desc &desc, u16 op)
case 0x0f: // R = Y
romcycles = cachecycles = 2U;
if (op & 0x0400U) // reserved field?
- desc.flags |= OPFLAG_INVALID_OPCODE;
+ desc.set_invalid_opcode();
describe_r(desc, op, false, true);
describe_y(desc, op, true, false);
break;
@@ -520,7 +543,7 @@ bool dsp16_device_base::frontend::describe_do(opcode_desc &desc, u16 op)
romcycles = 2U;
cachecycles = 1U;
if (op & 0x000fU)
- desc.flags |= OPFLAG_INVALID_OPCODE;
+ desc.set_invalid_opcode();
flag_input_reg(desc, BIT(op, 12) ? REG_BIT_DAU_A1 : REG_BIT_DAU_A0, REG_BIT_DAU_AUC);
flag_output_reg(desc, REG_BIT_DAU_Y);
describe_f1(desc, op);
@@ -554,7 +577,7 @@ bool dsp16_device_base::frontend::describe_do(opcode_desc &desc, u16 op)
case 0x18: // goto B
case 0x1a: // if CON # icall
case 0x1e: // Reserved
- desc.flags |= OPFLAG_INVALID_OPCODE;
+ desc.set_invalid_opcode();
m_cache_valid = false;
return false; // not going to get into what happens if you cache ineligible instructions
}
@@ -563,10 +586,11 @@ bool dsp16_device_base::frontend::describe_do(opcode_desc &desc, u16 op)
}
m_cache_cycles = cycles;
m_cache_last_cycles = cycles + (romcycles - cachecycles);
- m_cache_flags = desc.flags & (OPFLAG_READS_MEMORY | OPFLAG_WRITES_MEMORY);
- std::copy_n(desc.regin, std::size(desc.regin), m_cache_regin);
- std::copy_n(desc.regout, std::size(desc.regout), m_cache_regout);
- std::copy_n(desc.regreq, std::size(desc.regreq), m_cache_regreq);
+ m_cache_regin = desc.regin;
+ m_cache_regout = desc.regout;
+ m_cache_regreq = desc.regreq;
+ m_cache_reads_memory = desc.reads_memory();
+ m_cache_writes_memory = desc.writes_memory();
m_cache_valid = true;
desc.cycles += (2U - romcycles) + ((k - 1) * cycles) + (romcycles - cachecycles);
return true;
@@ -577,21 +601,24 @@ bool dsp16_device_base::frontend::describe_redo(opcode_desc &desc, u16 op)
desc.cycles = 2U;
u16 const k(op_k(op));
if (2U > k) // p3-25: "The iteration count can be between 2 and 127, inclusive"
- desc.flags |= OPFLAG_INVALID_OPCODE;
+ desc.set_invalid_opcode();
- // assume that the block follwoing the last do K { ... } we examined is still cached - we can check properly when we actually run
+ // assume that the block following the last do K { ... } we examined is still cached - we can check properly when we actually run
if (!m_cache_valid)
{
- desc.flags |= OPFLAG_INVALID_OPCODE;
+ desc.set_invalid_opcode();
return false;
}
else
{
desc.cycles += ((k - 1) * m_cache_cycles) + m_cache_last_cycles;
- desc.flags |= m_cache_flags;
- std::copy_n(m_cache_regin, std::size(desc.regin), desc.regin);
- std::copy_n(m_cache_regout, std::size(desc.regout), desc.regout);
- std::copy_n(m_cache_regreq, std::size(desc.regreq), desc.regreq);
+ desc.regin = m_cache_regin;
+ desc.regout = m_cache_regout;
+ desc.regreq = m_cache_regreq;
+ if (m_cache_reads_memory)
+ desc.set_reads_memory();
+ if (m_cache_writes_memory)
+ desc.set_writes_memory();
return true;
}
}
@@ -663,7 +690,7 @@ void dsp16_device_base::frontend::describe_r(opcode_desc &desc, u16 op, bool rea
case 0x1e: // pdx1
break;
default:
- desc.flags |= OPFLAG_INVALID_OPCODE;
+ desc.set_invalid_opcode();
}
}
@@ -680,7 +707,7 @@ void dsp16_device_base::frontend::describe_con(opcode_desc &desc, u16 op, bool i
flag_input_reg(desc, REG_BIT_DAU_PSW);
break;
case 0x4: // heads/tails
- throw emu_fatalerror("DSP16: unimplemented CON value %02X (PC = %04X)\n", con, desc.physpc);
+ throw emu_fatalerror("DSP16: unimplemented CON value %02X (PC = %04X)\n", con, desc.pc);
case 0x5: // c0ge/c0lt
case 0x6: // c1ge/c1lt
{
@@ -694,7 +721,7 @@ void dsp16_device_base::frontend::describe_con(opcode_desc &desc, u16 op, bool i
case 0x7: // true/false
break;
default:
- desc.flags |= OPFLAG_INVALID_OPCODE;
+ desc.set_invalid_opcode();
}
}
@@ -796,7 +823,7 @@ void dsp16_device_base::frontend::describe_f2(opcode_desc &desc, u16 op)
flag_output_reg(desc, d, REG_BIT_DAU_PSW);
break;
case 0xa: // Reserved
- desc.flags |= OPFLAG_INVALID_OPCODE;
+ desc.set_invalid_opcode();
break;
case 0xc: // aD = y
flag_input_reg(desc, REG_BIT_DAU_Y);
@@ -807,7 +834,7 @@ void dsp16_device_base::frontend::describe_f2(opcode_desc &desc, u16 op)
void dsp16_device_base::frontend::describe_x(opcode_desc &desc, u16 op)
{
- desc.flags |= OPFLAG_READS_MEMORY; // TODO: is reading ROM the same as memory for dependency purposes?
+ desc.set_reads_memory(); // TODO: is reading ROM the same as memory for dependency purposes?
flag_input_reg(desc, REG_BIT_XAAU_PT);
flag_output_reg(desc, REG_BIT_XAAU_PT, REG_BIT_DAU_X);
if (op_x(op))
@@ -818,9 +845,9 @@ void dsp16_device_base::frontend::describe_y(opcode_desc &desc, u16 op, bool rea
{
u32 const r(REG_BIT_YAAU_R0 + ((op >> 2) & 0x0003U));
if (read)
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_reads_memory();
if (write)
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_writes_memory();
switch (op & 0x0003U)
{
case 0x0: // *rN
@@ -845,7 +872,8 @@ void dsp16_device_base::frontend::describe_y(opcode_desc &desc, u16 op, bool rea
void dsp16_device_base::frontend::describe_z(opcode_desc &desc, u16 op)
{
u32 const r(REG_BIT_YAAU_R0 + ((op >> 2) & 0x0003U));
- desc.flags |= OPFLAG_READS_MEMORY | OPFLAG_WRITES_MEMORY;
+ desc.set_reads_memory();
+ desc.set_writes_memory();
flag_output_reg(desc, r);
switch (op & 0x0003U)
{
diff --git a/src/devices/cpu/dsp16/dsp16fe.h b/src/devices/cpu/dsp16/dsp16fe.h
index 8dc3b96700e..1045aa5e2aa 100644
--- a/src/devices/cpu/dsp16/dsp16fe.h
+++ b/src/devices/cpu/dsp16/dsp16fe.h
@@ -15,7 +15,37 @@
#include "cpu/drcfe.h"
-class dsp16_device_base::frontend : public drc_frontend
+class dsp16_device_base::opcode_desc : public opcode_desc_base<opcode_desc, 32>
+{
+public:
+ u32 cycles;
+
+ void set_can_change_modes() { m_can_change_modes = true; }
+ void set_reads_memory() { m_reads_memory = true; }
+ void set_writes_memory() { m_writes_memory = true; }
+
+ bool can_change_modes() const { return m_can_change_modes; }
+ bool reads_memory() const { return m_reads_memory; }
+ bool writes_memory() const { return m_writes_memory; }
+
+ void reset(offs_t curpc, bool in_delay_slot)
+ {
+ opcode_desc_base::reset(curpc, in_delay_slot);
+
+ cycles = 0;
+ m_can_change_modes = false;
+ m_reads_memory = false;
+ m_writes_memory = false;
+ }
+
+private:
+ bool m_can_change_modes;
+ bool m_reads_memory;
+ bool m_writes_memory;
+};
+
+
+class dsp16_device_base::frontend : public drc_frontend_base<opcode_desc>
{
public:
enum : u8
@@ -59,12 +89,13 @@ public:
// construction/destruction
frontend(dsp16_device_base &host, u32 window_start, u32 window_end, u32 max_sequence);
+ ~frontend();
-protected:
- // drc_frontend implementation
- virtual bool describe(opcode_desc &desc, opcode_desc const *prev) override;
+ opcode_desc const *describe_code(offs_t startpc);
private:
+ bool describe(opcode_desc &desc, opcode_desc const *prev);
+
// program fetch helpers
u16 read_op(opcode_desc const &desc, u16 offset);
u16 read_op(opcode_desc const &desc) { return read_op(desc, 0U); }
@@ -87,10 +118,10 @@ private:
static void describe_z(opcode_desc &desc, u16 op);
// field access helpers
- static void flag_reg(u32 (&flags)[4]) { }
- template <typename... T> static void flag_reg(u32 (&flags)[4], u8 reg0, T... regn)
+ static void flag_reg(opcode_desc::regmask &flags) { }
+ template <typename... T> static void flag_reg(opcode_desc::regmask &flags, u8 reg0, T... regn)
{
- flags[reg0 >> 5] |= (u32(1) << (reg0 & (u32(32) - 1)));
+ flags.set(reg0);
flag_reg(flags, regn...);
}
template <typename... T> static void flag_input_reg(opcode_desc &desc, T... reg) { flag_reg(desc.regin, reg...); }
@@ -101,8 +132,9 @@ private:
dsp16_device_base &m_host;
// for making sweeping assumptions
- u32 m_cache_cycles = 0U, m_cache_last_cycles = 0U, m_cache_flags = 0U;
- decltype(opcode_desc::regin) m_cache_regin, m_cache_regout, m_cache_regreq;
+ u32 m_cache_cycles = 0U, m_cache_last_cycles = 0U;
+ opcode_desc::regmask m_cache_regin, m_cache_regout, m_cache_regreq;
+ bool m_cache_reads_memory = false, m_cache_writes_memory = false;
bool m_cache_valid = false;
};
diff --git a/src/devices/cpu/dspp/dspp.cpp b/src/devices/cpu/dspp/dspp.cpp
index 92aa9cb7f06..9d7ed45d37b 100644
--- a/src/devices/cpu/dspp/dspp.cpp
+++ b/src/devices/cpu/dspp/dspp.cpp
@@ -142,7 +142,14 @@ dspp_bulldog_device::dspp_bulldog_device(const machine_config &mconfig, const ch
{
}
-dspp_device::dspp_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor code_map_ctor, address_map_constructor data_map_ctor) :
+dspp_device::dspp_device(
+ const machine_config &mconfig,
+ device_type type,
+ const char *tag,
+ device_t *owner,
+ uint32_t clock,
+ address_map_constructor code_map_ctor,
+ address_map_constructor data_map_ctor) :
cpu_device(mconfig, type, tag, owner, clock),
m_int_handler(*this),
m_dma_read_handler(*this, 0),
@@ -184,6 +191,10 @@ dspp_device::dspp_device(const machine_config &mconfig, device_type type, const
#endif
}
+dspp_device::~dspp_device()
+{
+}
+
//-------------------------------------------------
// device_start - start up the device
@@ -201,7 +212,7 @@ void dspp_device::device_start()
uint32_t flags = 0;
m_drcuml = std::make_unique<drcuml_state>(*this, m_cache, flags, 1, 16, 0);
- m_drcfe = std::make_unique<dspp_frontend>(this, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, SINGLE_INSTRUCTION_MODE ? 1 : COMPILE_MAX_SEQUENCE);
+ m_drcfe = std::make_unique<frontend>(this, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, SINGLE_INSTRUCTION_MODE ? 1 : COMPILE_MAX_SEQUENCE);
}
else
{
diff --git a/src/devices/cpu/dspp/dspp.h b/src/devices/cpu/dspp/dspp.h
index b7220dea5af..f5a2bd770b7 100644
--- a/src/devices/cpu/dspp/dspp.h
+++ b/src/devices/cpu/dspp/dspp.h
@@ -13,7 +13,6 @@
#pragma once
-#include "cpu/drcfe.h"
#include "cpu/drcuml.h"
@@ -21,18 +20,14 @@
// TYPE DEFINITIONS
//**************************************************************************
-class dspp_frontend;
-
// ======================> dspp_device
class dspp_device : public cpu_device
{
- friend class dspp_frontend;
public:
// Construction/destruction
- dspp_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor code_map_ctor,
- address_map_constructor data_map_ctor);
dspp_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ virtual ~dspp_device();
// Static configuration helpers
auto int_handler() { return m_int_handler.bind(); }
@@ -73,24 +68,36 @@ public:
void host_gw_control_write(offs_t offset, u16 data);
protected:
- // device-level overrides
+ class frontend;
+ class opcode_desc;
+
+ dspp_device(
+ const machine_config &mconfig,
+ device_type type,
+ const char *tag,
+ device_t *owner,
+ uint32_t clock,
+ address_map_constructor code_map_ctor,
+ address_map_constructor data_map_ctor);
+
+ // device_t implementation
virtual void device_start() override ATTR_COLD;
virtual void device_reset() override ATTR_COLD;
- // device_execute_interface overrides
+ // device_execute_interface implementation
virtual uint32_t execute_min_cycles() const noexcept override;
virtual uint32_t execute_max_cycles() const noexcept override;
virtual void execute_run() override;
- // device_memory_interface overrides
+ // device_memory_interface implementation
virtual space_config_vector memory_space_config() const override;
- // device_state_interface overrides
+ // device_state_interface implementation
virtual void state_import(const device_state_entry &entry) override;
virtual void state_export(const device_state_entry &entry) override;
virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
- // device_disasm_interface overrides
+ // device_disasm_interface implementation
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
void code_map(address_map &map) ATTR_COLD;
@@ -309,7 +316,7 @@ private:
bool m_cache_dirty;
drc_cache m_cache;
std::unique_ptr<drcuml_state> m_drcuml;
- std::unique_ptr<dspp_frontend> m_drcfe;
+ std::unique_ptr<frontend> m_drcfe;
uint32_t m_drcoptions;
/* internal compiler state */
diff --git a/src/devices/cpu/dspp/dsppdrc.cpp b/src/devices/cpu/dspp/dsppdrc.cpp
index 4992c0acf6d..6ba81c5baf5 100644
--- a/src/devices/cpu/dspp/dsppdrc.cpp
+++ b/src/devices/cpu/dspp/dsppdrc.cpp
@@ -35,11 +35,6 @@ inline void dspp_device::alloc_handle(code_handle **handleptr, const char *name)
*handleptr = m_drcuml->handle_alloc(name);
}
-static inline uint32_t epc(const opcode_desc *desc)
-{
- return desc->pc;
-}
-
#if 0
static void cfunc_unimplemented(void *param)
@@ -210,7 +205,7 @@ void dspp_device::compile_block(offs_t pc)
/* determine the last instruction in this sequence */
for (seqlast = seqhead; seqlast != nullptr; seqlast = seqlast->next())
- if (seqlast->flags & OPFLAG_END_SEQUENCE)
+ if (seqlast->end_sequence())
break;
assert(seqlast != nullptr);
@@ -238,7 +233,7 @@ void dspp_device::compile_block(offs_t pc)
generate_checksum_block(block, &compiler, seqhead, seqlast);
/* label this instruction, if it may be jumped to locally */
- if (seqhead->flags & OPFLAG_IS_BRANCH_TARGET)
+ if (seqhead->is_branch_target())
UML_LABEL(block, seqhead->pc | 0x80000000); // label seqhead->pc
compiler.abortlabel = compiler.labelnum++;
@@ -249,7 +244,7 @@ void dspp_device::compile_block(offs_t pc)
UML_LABEL(block, compiler.abortlabel);
/* if we need to return to the start, do it */
- if (seqlast->flags & OPFLAG_RETURN_TO_START)
+ if (seqlast->return_to_start())
nextpc = pc;
/* otherwise we just go to the next instruction */
@@ -281,13 +276,13 @@ void dspp_device::generate_checksum_block(drcuml_block &block, compiler_state *c
if (m_drcuml->logging())
block.append_comment("[Validation for %08X]", seqhead->pc); // comment
- /* loose verify or single instruction: just compare and fail */
if (false/*!(m_drcoptions & DSPPDRC_STRICT_VERIFY)*/ || seqhead->next() == nullptr)
{
- if (!(seqhead->flags & OPFLAG_VIRTUAL_NOOP))
+ // loose verify or single instruction: just compare and fail
+ if (!seqhead->virtual_noop())
{
- uint32_t sum = seqhead->opptr.w[0];
- uint32_t addr = seqhead->physpc;
+ uint32_t sum = seqhead->opptr[0];
+ uint32_t addr = seqhead->pc;
const void *base = m_code_cache.read_ptr(addr);
UML_MOV(block, I0, 0);
UML_LOAD(block, I0, base, 0, SIZE_WORD, SCALE_x2); // load i0,base,0,word
@@ -296,27 +291,28 @@ void dspp_device::generate_checksum_block(drcuml_block &block, compiler_state *c
UML_EXHc(block, COND_NE, *m_nocode, seqhead->pc); // exne nocode,seqhead->pc
}
}
-
- /* full verification; sum up everything */
else
{
+ // full verification; sum up everything
uint32_t sum = 0;
- uint32_t addr = seqhead->physpc;
+ uint32_t addr = seqhead->pc;
const void *base = m_code_cache.read_ptr(addr);
UML_LOAD(block, I0, base, 0, SIZE_WORD, SCALE_x2); // load i0,base,0,dword
- sum += seqhead->opptr.w[0];
+ sum += seqhead->opptr[0];
for (curdesc = seqhead->next(); curdesc != seqlast->next(); curdesc = curdesc->next())
- if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP))
+ {
+ if (!curdesc->virtual_noop())
{
- addr = curdesc->physpc;
+ addr = curdesc->pc;
base = m_code_cache.read_ptr(addr);
assert(base != nullptr);
UML_LOAD(block, I1, base, 0, SIZE_WORD, SCALE_x2); // load i1,base,dword
UML_ADD(block, I0, I0, I1); // add i0,i0,i1
- sum += curdesc->opptr.w[0];
+ sum += curdesc->opptr[0];
}
+ }
UML_CMP(block, I0, sum); // cmp i0,sum
- UML_EXHc(block, COND_NE, *m_nocode, epc(seqhead)); // exne nocode,seqhead->pc
+ UML_EXHc(block, COND_NE, *m_nocode, seqhead->epc()); // exne nocode,seqhead->pc
}
}
@@ -414,16 +410,8 @@ void dspp_device::generate_sequence_instruction(drcuml_block &block, compiler_st
UML_DEBUG(block, desc->pc); // debug desc->pc
}
- /* if we hit an unmapped address, fatal error */
- if (desc->flags & OPFLAG_COMPILER_UNMAPPED)
- {
- UML_MOV(block, mem(&m_core->m_pc), desc->pc); // mov [pc],desc->pc
- save_fast_iregs(block); // <save fastregs>
- UML_EXIT(block, EXECUTE_UNMAPPED_CODE); // exit EXECUTE_UNMAPPED_CODE
- }
-
/* unless this is a virtual no-op, it's a regular instruction */
- if (!(desc->flags & OPFLAG_VIRTUAL_NOOP))
+ if (!desc->virtual_noop())
{
generate_opcode(block, compiler, desc);
}
@@ -443,7 +431,7 @@ void dspp_device::generate_update_cycles(drcuml_block &block, compiler_state *co
void dspp_device::generate_opcode(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc)
{
- uint16_t op = desc->opptr.w[0];
+ uint16_t op = desc->opptr[0];
UML_SUB(block, mem(&m_core->m_tclock), mem(&m_core->m_tclock), 1);
UML_CALLC(block, cfunc_update_fifo_dma, this);
@@ -457,7 +445,7 @@ void dspp_device::generate_opcode(drcuml_block &block, compiler_state *compiler,
//UML_TEST(block, mem(&m_core->m_flag_sleep), 1);
//UML_JMPc(block, COND_NZ, compiler->abortlabel);
- //UML_MOV(block, mem(&m_core->m_arg0), desc->physpc);
+ //UML_MOV(block, mem(&m_core->m_arg0), desc->pc);
//UML_MOV(block, mem(&m_core->m_arg1), op);
//UML_CALLC(block, cfunc_print_sums, this);
@@ -509,7 +497,7 @@ void dspp_device::generate_set_rbase(drcuml_block &block, compiler_state *compil
void dspp_device::generate_super_special(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc)
{
- uint16_t op = desc->opptr.w[0];
+ uint16_t op = desc->opptr[0];
uint32_t sel = (op >> 7) & 7;
switch (sel)
@@ -560,7 +548,7 @@ void dspp_device::generate_super_special(drcuml_block &block, compiler_state *co
void dspp_device::generate_special_opcode(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc)
{
- uint16_t op = desc->opptr.w[0];
+ uint16_t op = desc->opptr[0];
switch ((op >> 10) & 7)
{
@@ -666,7 +654,7 @@ void dspp_device::generate_branch(drcuml_block &block, compiler_state *compiler,
if (desc->targetpc != BRANCH_TARGET_DYNAMIC)
{
generate_update_cycles(block, &compiler_temp, desc->targetpc); // <subtract cycles>
- if (desc->flags & OPFLAG_INTRABLOCK_BRANCH)
+ if (desc->intrablock_branch())
UML_JMP(block, desc->targetpc | 0x80000000); // jmp desc->targetpc | 0x80000000
else
UML_HASHJMP(block, 0, desc->targetpc, *m_nocode); // hashjmp <mode>,desc->targetpc,nocode
@@ -686,7 +674,7 @@ void dspp_device::generate_branch(drcuml_block &block, compiler_state *compiler,
void dspp_device::generate_branch_opcode(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc)
{
- uint16_t op = desc->opptr.w[0];
+ uint16_t op = desc->opptr[0];
if (m_drcuml->logging())
block.append_comment("branch_opcode");
@@ -734,7 +722,7 @@ void dspp_device::generate_branch_opcode(drcuml_block &block, compiler_state *co
void dspp_device::generate_complex_branch_opcode(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc)
{
- uint16_t op = desc->opptr.w[0];
+ uint16_t op = desc->opptr[0];
switch ((op >> 10) & 7)
{
@@ -929,7 +917,7 @@ void dspp_device::generate_parse_operands(drcuml_block &block, compiler_state *c
void dspp_device::generate_read_next_operand(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc)
{
- //uint16_t op = (uint16_t)desc->opptr.w[0];
+ //uint16_t op = desc->opptr[0];
code_label no_load;
if (m_drcuml->logging())
@@ -977,7 +965,7 @@ void dspp_device::generate_write_next_operand(drcuml_block &block, compiler_stat
void dspp_device::generate_arithmetic_opcode(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc)
{
- uint16_t op = (uint16_t)desc->opptr.w[0];
+ uint16_t op = desc->opptr[0];
uint32_t numops = (op >> 13) & 3;
uint32_t muxa = (op >> 10) & 3;
uint32_t muxb = (op >> 8) & 3;
diff --git a/src/devices/cpu/dspp/dsppfe.cpp b/src/devices/cpu/dspp/dsppfe.cpp
index 19b2cb1a3b8..f614a327bc9 100644
--- a/src/devices/cpu/dspp/dsppfe.cpp
+++ b/src/devices/cpu/dspp/dsppfe.cpp
@@ -10,71 +10,32 @@
#include "emu.h"
#include "dsppfe.h"
+#include "cpu/drcfe.ipp"
-//#define REG_USED(desc,x) do { (desc).regin[0] |= 1 << (x); } while(0)
-//#define REG_MODIFIED(desc,x) do { (desc).regout[0] |= 1 << (x); } while(0)
-
-#define CC_C_USED(desc) do { (desc).regin[0] |= 1 << 16; } while(0)
-#define CC_C_MODIFIED(desc) do { (desc).regout[0] |= 1 << 16; } while(0)
-#define CC_Z_USED(desc) do { (desc).regin[0] |= 1 << 16; } while(0)
-#define CC_Z_MODIFIED(desc) do { (desc).regout[0] |= 1 << 16; } while(0)
-#define CC_N_USED(desc) do { (desc).regin[0] |= 1 << 16; } while(0)
-#define CC_N_MODIFIED(desc) do { (desc).regout[0] |= 1 << 16; } while(0)
-#define CC_V_USED(desc) do { (desc).regin[0] |= 1 << 16; } while(0)
-#define CC_V_MODIFIED(desc) do { (desc).regout[0] |= 1 << 16; } while(0)
-#define CC_X_USED(desc) do { (desc).regin[0] |= 1 << 16; } while(0)
-#define CC_X_MODIFIED(desc) do { (desc).regout[0] |= 1 << 16; } while(0)
-
-#define CC_FLAGS_MODIFIED(desc) do { } while(0)
-
-dspp_frontend::dspp_frontend(dspp_device *dspp, uint32_t window_start, uint32_t window_end, uint32_t max_sequence)
- : drc_frontend(*dspp, window_start, window_end, max_sequence),
- m_dspp(dspp)
+
+dspp_device::frontend::frontend(dspp_device *dspp, uint32_t window_start, uint32_t window_end, uint32_t max_sequence)
+ : drc_frontend_base(dspp->space_config(AS_PROGRAM)->page_shift(), window_start, window_end, max_sequence)
+ , m_dspp(dspp)
+{
+
+}
+
+dspp_device::frontend::~frontend()
{
+}
+
+dspp_device::opcode_desc const *dspp_device::frontend::describe_code(offs_t startpc)
+{
+ return do_describe_code(
+ [this] (opcode_desc &desc, opcode_desc const *prev) { return describe(desc, prev); },
+ startpc);
}
-#if 0
-// opcode branch flags
-const uint32_t OPFLAG_IS_UNCONDITIONAL_BRANCH = 0x00000001; // instruction is unconditional branch
-const uint32_t OPFLAG_IS_CONDITIONAL_BRANCH = 0x00000002; // instruction is conditional branch
-const uint32_t OPFLAG_IS_BRANCH = (OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_IS_CONDITIONAL_BRANCH);
-const uint32_t OPFLAG_IS_BRANCH_TARGET = 0x00000004; // instruction is the target of a branch
-const uint32_t OPFLAG_IN_DELAY_SLOT = 0x00000008; // instruction is in the delay slot of a branch
-const uint32_t OPFLAG_INTRABLOCK_BRANCH = 0x00000010; // instruction branches within the block
-
-// opcode exception flags
-const uint32_t OPFLAG_CAN_TRIGGER_SW_INT = 0x00000020; // instruction can trigger a software interrupt
-const uint32_t OPFLAG_CAN_EXPOSE_EXTERNAL_INT = 0x00000040; // instruction can expose an external interrupt
-const uint32_t OPFLAG_CAN_CAUSE_EXCEPTION = 0x00000080; // instruction may generate exception
-const uint32_t OPFLAG_WILL_CAUSE_EXCEPTION = 0x00000100; // instruction will generate exception
-const uint32_t OPFLAG_PRIVILEGED = 0x00000200; // instruction is privileged
-
-// opcode virtual->physical translation flags
-const uint32_t OPFLAG_VALIDATE_TLB = 0x00000400; // instruction must validate TLB before execution
-const uint32_t OPFLAG_MODIFIES_TRANSLATION = 0x00000800; // instruction modifies the TLB
-const uint32_t OPFLAG_COMPILER_PAGE_FAULT = 0x00001000; // compiler hit a page fault when parsing
-const uint32_t OPFLAG_COMPILER_UNMAPPED = 0x00002000; // compiler hit unmapped memory when parsing
-
-// opcode flags
-const uint32_t OPFLAG_INVALID_OPCODE = 0x00004000; // instruction is invalid
-const uint32_t OPFLAG_VIRTUAL_NOOP = 0x00008000; // instruction is a virtual no-op
-
-// opcode sequence flow flags
-const uint32_t OPFLAG_REDISPATCH = 0x00010000; // instruction must redispatch after completion
-const uint32_t OPFLAG_RETURN_TO_START = 0x00020000; // instruction must jump back to the beginning after completion
-const uint32_t OPFLAG_END_SEQUENCE = 0x00040000; // this is the last instruction in a sequence
-const uint32_t OPFLAG_CAN_CHANGE_MODES = 0x00080000; // instruction can change modes
-
-// execution semantics
-const uint32_t OPFLAG_READS_MEMORY = 0x00100000; // instruction reads memory
-const uint32_t OPFLAG_WRITES_MEMORY = 0x00200000; // instruction writes memory
-#endif
-
-bool dspp_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
+bool dspp_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev)
{
- uint16_t op = desc.opptr.w[0] = m_dspp->read_op(desc.physpc);
+ const uint16_t op = desc.opptr[0] = m_dspp->read_op(desc.pc);
desc.cycles = 1;
desc.length = 1;
@@ -104,7 +65,7 @@ bool dspp_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
return true;
}
-void dspp_frontend::describe_special(uint16_t op, opcode_desc &desc)
+void dspp_device::frontend::describe_special(uint16_t op, opcode_desc &desc)
{
switch ((op >> 10) & 7)
{
@@ -115,13 +76,15 @@ void dspp_frontend::describe_special(uint16_t op, opcode_desc &desc)
{
case 1: // BAC
{
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
desc.targetpc = BRANCH_TARGET_DYNAMIC;
return;
}
case 4: // RTS
{
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
desc.targetpc = BRANCH_TARGET_DYNAMIC;
return;
}
@@ -133,7 +96,8 @@ void dspp_frontend::describe_special(uint16_t op, opcode_desc &desc)
case 7: // SLEEP
{
- desc.flags |= OPFLAG_END_SEQUENCE | OPFLAG_RETURN_TO_START;
+ desc.set_end_sequence();
+ desc.set_return_to_start();
return;
}
@@ -148,13 +112,15 @@ void dspp_frontend::describe_special(uint16_t op, opcode_desc &desc)
}
case 1: // JUMP
{
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
desc.targetpc = op & 0x3ff;
return;
}
case 2: // JSR
{
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
desc.targetpc = op & 0x3ff;
return;
}
@@ -165,11 +131,11 @@ void dspp_frontend::describe_special(uint16_t op, opcode_desc &desc)
}
case 4: // MOVEREG
{
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_writes_memory();
// Indirect
if (op & 0x0010)
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_reads_memory();
parse_operands(op, desc, 1);
return;
@@ -180,84 +146,85 @@ void dspp_frontend::describe_special(uint16_t op, opcode_desc &desc)
}
case 6: // MOVED
{
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_writes_memory();
parse_operands(op, desc, 1);
return;
}
case 7: // MOVEI
{
- desc.flags |= OPFLAG_READS_MEMORY | OPFLAG_WRITES_MEMORY;
+ desc.set_reads_memory();
+ desc.set_writes_memory();
parse_operands(op, desc, 1);
return;
}
}
}
-void dspp_frontend::describe_branch(uint16_t op, opcode_desc &desc)
+void dspp_device::frontend::describe_branch(uint16_t op, opcode_desc &desc)
{
const uint32_t select = (op >> 12) & 1;
if (select == 0)
{
- CC_N_USED(desc);
- CC_V_USED(desc);
+ desc.set_cc_n_used();
+ desc.set_cc_v_used();
}
else
{
- CC_C_USED(desc);
- CC_Z_USED(desc);
+ desc.set_cc_c_used();
+ desc.set_cc_z_used();
}
// TODO: Can these be unconditional?
- desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+ desc.set_is_conditional_branch();
desc.targetpc = op & 0x3ff;
}
-void dspp_frontend::describe_complex_branch(uint16_t op, opcode_desc &desc)
+void dspp_device::frontend::describe_complex_branch(uint16_t op, opcode_desc &desc)
{
switch ((op >> 10) & 7)
{
case 0: // BLT
- CC_N_USED(desc);
- CC_V_USED(desc);
+ desc.set_cc_n_used();
+ desc.set_cc_v_used();
break;
case 1: // BLE
- CC_N_USED(desc);
- CC_V_USED(desc);
- CC_Z_USED(desc);
+ desc.set_cc_n_used();
+ desc.set_cc_v_used();
+ desc.set_cc_z_used();
break;
case 2: // BGE
- CC_N_USED(desc);
- CC_V_USED(desc);
+ desc.set_cc_n_used();
+ desc.set_cc_v_used();
break;
case 3: // BGT
- CC_N_USED(desc);
- CC_V_USED(desc);
- CC_Z_USED(desc);
+ desc.set_cc_n_used();
+ desc.set_cc_v_used();
+ desc.set_cc_z_used();
break;
case 4: // BHI
case 5: // BLS
- CC_C_USED(desc);
- CC_Z_USED(desc);
+ desc.set_cc_c_used();
+ desc.set_cc_z_used();
break;
case 6: // BXS
case 7: // BXC
- CC_X_USED(desc);
+ desc.set_cc_x_used();
break;
}
- desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+ desc.set_is_conditional_branch();
desc.targetpc = op & 0x3ff;
}
-void dspp_frontend::describe_arithmetic(uint16_t op, opcode_desc &desc)
+void dspp_device::frontend::describe_arithmetic(uint16_t op, opcode_desc &desc)
{
// Decode the various fields
uint32_t numops = (op >> 13) & 3;
- uint32_t muxa = (op >> 10) & 3;
- uint32_t muxb = (op >> 8) & 3;
- uint32_t alu_op = (op >> 4) & 0xf;
- uint32_t barrel_code = op & 0xf;
+ const uint32_t muxa = (op >> 10) & 3;
+ const uint32_t muxb = (op >> 8) & 3;
+ const uint32_t alu_op = (op >> 4) & 0xf;
+ const uint32_t barrel_code = op & 0xf;
// Check for operand overflow
if (numops == 0 && ((muxa == 1) || (muxa == 2) || (muxb == 1) || (muxb == 2)))
@@ -278,7 +245,7 @@ void dspp_frontend::describe_arithmetic(uint16_t op, opcode_desc &desc)
if (muxa > 0 || muxb > 0)
{
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_reads_memory();
}
switch (alu_op)
@@ -304,32 +271,32 @@ void dspp_frontend::describe_arithmetic(uint16_t op, opcode_desc &desc)
case 14: // _XOR
case 15: // _XNOR
{
- CC_C_MODIFIED(desc);
- CC_V_MODIFIED(desc);
+ desc.set_cc_c_modified();
+ desc.set_cc_v_modified();
break;
}
case 3: // _+C
case 5: // _-B
{
- CC_C_USED(desc);
- CC_C_MODIFIED(desc);
+ desc.set_cc_c_used();
+ desc.set_cc_c_modified();
break;
}
}
- CC_N_MODIFIED(desc);
- CC_Z_MODIFIED(desc);
- CC_X_MODIFIED(desc);
+ desc.set_cc_n_modified();
+ desc.set_cc_z_modified();
+ desc.set_cc_x_modified();
}
-void dspp_frontend::parse_operands(uint16_t op, opcode_desc &desc, uint32_t numops)
+void dspp_device::frontend::parse_operands(uint16_t op, opcode_desc &desc, uint32_t numops)
{
uint32_t numregs = 0;
uint32_t opidx = 0;
while (opidx < numops)
{
- uint16_t operand = desc.opptr.w[opidx + 1] = m_dspp->read_op(desc.physpc + opidx + 1);
+ uint16_t operand = desc.opptr[opidx + 1] = m_dspp->read_op(desc.pc + opidx + 1);
desc.length++;
desc.cycles++;
@@ -344,10 +311,10 @@ void dspp_frontend::parse_operands(uint16_t op, opcode_desc &desc, uint32_t numo
else if((operand & 0xe000) == 0x8000)
{
if (operand & 0x0400) // Indirect
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_reads_memory();
if (operand & 0x0800 )// Write Back
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_writes_memory();
opidx++;
}
@@ -373,21 +340,21 @@ void dspp_frontend::parse_operands(uint16_t op, opcode_desc &desc, uint32_t numo
if (regdi & 0x0010)
{
// Indirect
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_reads_memory();
}
if (numregs == 2)
{
// Write back
if ((i == 0) && (operand & 0x1000))
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_writes_memory();
else if ((i == 1) && (operand & 0x0800))
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_writes_memory();
}
else if (numregs == 1)
{
if (operand & 0x800)
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_writes_memory();
}
opidx++;
}
diff --git a/src/devices/cpu/dspp/dsppfe.h b/src/devices/cpu/dspp/dsppfe.h
index 5c0023e313a..b4eccfda3ee 100644
--- a/src/devices/cpu/dspp/dsppfe.h
+++ b/src/devices/cpu/dspp/dsppfe.h
@@ -14,51 +14,81 @@
#pragma once
#include "dspp.h"
+
#include "cpu/drcfe.h"
+#include <cassert>
+#include <algorithm>
+
//**************************************************************************
-// MACROS
+// TYPE DEFINITIONS
//**************************************************************************
-// register flags 0
-#define REGFLAG_R(n) (1 << (n))
-#define REGFLAG_RZ(n) (((n) == 0) ? 0 : REGFLAG_R(n))
+class dspp_device::opcode_desc : public opcode_desc_base<opcode_desc, 16>
+{
+public:
+ uint16_t opptr[6]; // copy of opcode and operands
-// register flags 1
-#define REGFLAG_FR(n) (1 << (n))
+ uint32_t cycles; // number of cycles needed to execute
-// register flags 2
-#define REGFLAG_CR(n) (0xf0000000 >> (4 * (n)))
-#define REGFLAG_CR_BIT(n) (0x80000000 >> (n))
+ void set_cc_c_used() { regin.set(REG_CC_C); }
+ void set_cc_c_modified() { regout.set(REG_CC_C); }
+ void set_cc_z_used() { regin.set(REG_CC_Z); }
+ void set_cc_z_modified() { regout.set(REG_CC_Z); }
+ void set_cc_n_used() { regin.set(REG_CC_N); }
+ void set_cc_n_modified() { regout.set(REG_CC_N); }
+ void set_cc_v_used() { regin.set(REG_CC_V); }
+ void set_cc_v_modified() { regout.set(REG_CC_V); }
+ void set_cc_x_used() { regin.set(REG_CC_X); }
+ void set_cc_x_modified() { regout.set(REG_CC_X); }
-// register flags 3
-#define REGFLAG_XER_CA (1 << 0)
-#define REGFLAG_XER_OV (1 << 1)
-#define REGFLAG_XER_SO (1 << 2)
-#define REGFLAG_XER_COUNT (1 << 3)
-#define REGFLAG_CTR (1 << 4)
-#define REGFLAG_LR (1 << 5)
-#define REGFLAG_FPSCR(n) (1 << (6 + (n)))
+ void set_reads_memory() { m_reads_memory = true; }
+ void set_writes_memory() { m_writes_memory = true; }
+ bool reads_memory() const { return m_reads_memory; }
+ bool writes_memory() const { return m_writes_memory; }
+ uint32_t epc() const { return pc; }
+
+ void reset(offs_t curpc, bool in_delay_slot)
+ {
+ static_assert(REG_COUNT <= 16);
+
+ opcode_desc_base::reset(curpc, in_delay_slot);
+
+ std::fill(std::begin(opptr), std::end(opptr), 0);
+ cycles = 0;
+ }
+
+private:
+ enum
+ {
+ REG_CC_C = 0,
+ REG_CC_Z,
+ REG_CC_N,
+ REG_CC_V,
+ REG_CC_X,
+
+ REG_COUNT
+ };
+
+ bool m_reads_memory;
+ bool m_writes_memory;
+};
-//**************************************************************************
-// TYPE DEFINITIONS
-//**************************************************************************
-class dspp_frontend : public drc_frontend
+class dspp_device::frontend : public drc_frontend_base<opcode_desc>
{
public:
// construction/destruction
- dspp_frontend(dspp_device *dspp, uint32_t window_start, uint32_t window_end, uint32_t max_sequence);
+ frontend(dspp_device *dspp, uint32_t window_start, uint32_t window_end, uint32_t max_sequence);
+ ~frontend();
-protected:
- // required overrides
- virtual bool describe(opcode_desc &desc, const opcode_desc *prev) override;
+ opcode_desc const *describe_code(offs_t startpc);
private:
- // inlines
+ bool describe(opcode_desc &desc, opcode_desc const *prev);
// internal helpers
void describe_special(uint16_t op, opcode_desc &desc);
diff --git a/src/devices/cpu/e132xs/e132xs.cpp b/src/devices/cpu/e132xs/e132xs.cpp
index b3a44a8f923..6d4b1792552 100644
--- a/src/devices/cpu/e132xs/e132xs.cpp
+++ b/src/devices/cpu/e132xs/e132xs.cpp
@@ -1620,7 +1620,7 @@ void hyperstone_device::device_start()
m_drcuml->symbol_add(&m_core->arg1, sizeof(uint32_t), "arg1");
// initialize the front-end helper
- m_drcfe = std::make_unique<e132xs_frontend>(*this, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, m_single_instruction_mode ? 1 : COMPILE_MAX_SEQUENCE);
+ m_drcfe = std::make_unique<frontend>(*this, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, m_single_instruction_mode ? 1 : COMPILE_MAX_SEQUENCE);
// generate invariant code
generate_invariant();
diff --git a/src/devices/cpu/e132xs/e132xs.h b/src/devices/cpu/e132xs/e132xs.h
index 17b8012480b..a04c9762812 100644
--- a/src/devices/cpu/e132xs/e132xs.h
+++ b/src/devices/cpu/e132xs/e132xs.h
@@ -7,9 +7,7 @@
#include "32xsdasm.h"
-#include "cpu/drcfe.h"
#include "cpu/drcuml.h"
-#include "cpu/drcumlsh.h"
#include <utility>
@@ -44,9 +42,6 @@
// TYPE DEFINITIONS
//**************************************************************************
-class e132xs_frontend;
-
-
enum
{
E132XS_PC = 1,
@@ -107,8 +102,6 @@ enum
// Used by core CPU interface
class hyperstone_device : public cpu_device, public hyperstone_disassembler::config
{
- friend class e132xs_frontend;
-
public:
// input line numbers
static inline constexpr int INPUT_INT1 = 0;
@@ -125,6 +118,9 @@ public:
virtual ~hyperstone_device() override;
protected:
+ class frontend;
+ class opcode_desc;
+
using b_r_delegate = delegate<uint8_t (offs_t)>;
using hw_r_delegate = delegate<uint16_t (offs_t)>;
using w_r_delegate = delegate<uint32_t (offs_t)>;
@@ -445,7 +441,7 @@ private:
drc_cache m_cache;
std::unique_ptr<drcuml_state> m_drcuml;
- std::unique_ptr<e132xs_frontend> m_drcfe;
+ std::unique_ptr<frontend> m_drcfe;
uint32_t m_drcoptions;
bool m_single_instruction_mode;
uint8_t m_cache_dirty;
diff --git a/src/devices/cpu/e132xs/e132xsdrc.cpp b/src/devices/cpu/e132xs/e132xsdrc.cpp
index 597f7576eb8..88b7bdc11fa 100644
--- a/src/devices/cpu/e132xs/e132xsdrc.cpp
+++ b/src/devices/cpu/e132xs/e132xsdrc.cpp
@@ -3,8 +3,11 @@
#include "emu.h"
#include "e132xs.h"
-#include "e132xsfe.h"
+
#include "32xsdefs.h"
+#include "e132xsfe.h"
+
+#include "cpu/drcumlsh.h"
/* map variables */
@@ -14,17 +17,6 @@
/*-------------------------------------------------
- epc - compute the exception PC from a
- descriptor
--------------------------------------------------*/
-
-static inline uint32_t epc(const opcode_desc *desc)
-{
- return (desc->flags & OPFLAG_IN_DELAY_SLOT) ? desc->branch->pc : desc->pc;
-}
-
-
-/*-------------------------------------------------
alloc_handle - allocate a handle if not
already allocated
-------------------------------------------------*/
@@ -294,7 +286,7 @@ void hyperstone_device::code_compile_block(uint8_t mode, offs_t pc)
/* determine the last instruction in this sequence */
for (seqlast = seqhead; seqlast != nullptr; seqlast = seqlast->next())
- if (seqlast->flags & OPFLAG_END_SEQUENCE)
+ if (seqlast->end_sequence())
break;
assert(seqlast != nullptr);
@@ -319,11 +311,11 @@ void hyperstone_device::code_compile_block(uint8_t mode, offs_t pc)
}
// validate this code block if we're not pointing into ROM
- if (m_program->get_write_ptr(seqhead->physpc) != nullptr)
+ if (m_program->get_write_ptr(seqhead->pc) != nullptr)
generate_checksum_block(block, compiler, seqhead, seqlast);
// label this instruction, if it may be jumped to locally
- if (seqhead->flags & OPFLAG_IS_BRANCH_TARGET)
+ if (seqhead->is_branch_target())
UML_LABEL(block, seqhead->pc | 0x80000000);
UML_MOV(block, I7, 0);
@@ -337,7 +329,7 @@ void hyperstone_device::code_compile_block(uint8_t mode, offs_t pc)
}
uint32_t nextpc;
- if (seqlast->flags & OPFLAG_RETURN_TO_START) /* if we need to return to the start, do it */
+ if (seqlast->return_to_start()) /* if we need to return to the start, do it */
nextpc = pc;
else /* otherwise we just go to the next instruction */
nextpc = seqlast->pc + seqlast->length;
@@ -695,10 +687,10 @@ void hyperstone_device::generate_checksum_block(drcuml_block &block, compiler_st
/* loose verify or single instruction: just compare and fail */
if (!(m_drcoptions & E132XS_STRICT_VERIFY) || !seqhead->next())
{
- if (!(seqhead->flags & OPFLAG_VIRTUAL_NOOP))
+ if (!seqhead->virtual_noop())
{
- uint32_t sum = seqhead->opptr.w[0];
- uint32_t addr = seqhead->physpc;
+ uint32_t sum = seqhead->opptr[0];
+ uint32_t addr = seqhead->pc;
const void *base = m_prptr(addr);
if (!base)
{
@@ -708,32 +700,32 @@ void hyperstone_device::generate_checksum_block(drcuml_block &block, compiler_st
auto const *delayslot = seqhead->delay.first();
const void *delaybase = nullptr;
- if (delayslot && (seqhead->physpc != delayslot->physpc))
+ if (delayslot && (seqhead->pc != delayslot->pc))
{
- delaybase = m_prptr(delayslot->physpc);
+ delaybase = m_prptr(delayslot->pc);
if (!delaybase)
{
- osd_printf_info("%s: cache read_ptr returned nullptr for address %08x\n", tag(), delayslot->physpc);
+ osd_printf_info("%s: cache read_ptr returned nullptr for address %08x\n", tag(), delayslot->pc);
}
}
UML_LOAD(block, I0, base, 0, SIZE_WORD, SCALE_x1);
- if (delayslot && (seqhead->physpc != delayslot->physpc))
+ if (delayslot && (seqhead->pc != delayslot->pc))
{
UML_LOAD(block, I1, delaybase, 0, SIZE_WORD, SCALE_x1);
UML_ADD(block, I0, I0, I1);
- sum += delayslot->opptr.w[0];
+ sum += delayslot->opptr[0];
}
UML_CMP(block, I0, sum);
- UML_EXHc(block, COND_NE, *m_nocode, epc(seqhead));
+ UML_EXHc(block, COND_NE, *m_nocode, seqhead->epc());
}
}
else /* full verification; sum up everything */
{
- uint32_t addr = seqhead->physpc;
+ uint32_t addr = seqhead->pc;
const void *base = m_prptr(addr);
if (!base)
{
@@ -743,32 +735,32 @@ void hyperstone_device::generate_checksum_block(drcuml_block &block, compiler_st
UML_LOAD(block, I0, base, 0, SIZE_WORD, SCALE_x1);
- uint32_t sum = seqhead->opptr.w[0];
+ uint32_t sum = seqhead->opptr[0];
for (curdesc = seqhead->next(); curdesc != seqlast->next(); curdesc = curdesc->next())
{
- if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP))
+ if (!curdesc->virtual_noop())
{
- addr = curdesc->physpc;
+ addr = curdesc->pc;
base = m_prptr(addr);
assert(base != nullptr);
UML_LOAD(block, I1, base, 0, SIZE_WORD, SCALE_x1);
UML_ADD(block, I0, I0, I1);
- sum += curdesc->opptr.w[0];
+ sum += curdesc->opptr[0];
- if (curdesc->delay.first() != nullptr && (curdesc == seqlast || (curdesc->next() != nullptr && curdesc->next()->physpc != curdesc->delay.first()->physpc)))
+ if (curdesc->delay.first() != nullptr && (curdesc == seqlast || (curdesc->next() != nullptr && curdesc->next()->pc != curdesc->delay.first()->pc)))
{
- addr = curdesc->delay.first()->physpc;
+ addr = curdesc->delay.first()->pc;
base = m_prptr(addr);
assert(base != nullptr);
UML_LOAD(block, I1, base, 0, SIZE_WORD, SCALE_x1);
UML_ADD(block, I0, I0, I1);
- sum += curdesc->delay.first()->opptr.w[0];
+ sum += curdesc->delay.first()->opptr[0];
}
}
}
UML_CMP(block, I0, sum);
- UML_EXHc(block, COND_NE, *m_nocode, epc(seqhead));
+ UML_EXHc(block, COND_NE, *m_nocode, seqhead->epc());
}
}
@@ -800,7 +792,7 @@ void hyperstone_device::generate_branch(drcuml_block &block, compiler_state &com
generate_update_cycles(block);
- if (desc && (mode == compiler.mode()) && (desc->flags & OPFLAG_INTRABLOCK_BRANCH))
+ if (desc && (mode == compiler.mode()) && desc->intrablock_branch())
{
assert(desc->targetpc != BRANCH_TARGET_DYNAMIC);
@@ -831,8 +823,8 @@ void hyperstone_device::generate_branch(drcuml_block &block, compiler_state &com
void hyperstone_device::generate_sequence_instruction(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc)
{
// add an entry for the log
- if (m_drcuml->logging() && !(desc->flags & OPFLAG_VIRTUAL_NOOP))
- log_add_disasm_comment(block, desc->pc, desc->opptr.w[0]);
+ if (m_drcuml->logging() && !desc->virtual_noop())
+ log_add_disasm_comment(block, desc->pc, desc->opptr[0]);
// check for pending interrupts
UML_SUB(block, I0, mem(&m_core->intblock), 1);
@@ -851,7 +843,7 @@ void hyperstone_device::generate_sequence_instruction(drcuml_block &block, compi
UML_DEBUG(block, desc->pc);
}
- if (!(desc->flags & OPFLAG_VIRTUAL_NOOP))
+ if (!desc->virtual_noop())
{
// set the PC map variable
UML_MAPVAR(block, MAPVAR_PC, compiler.set_pc(desc->pc + desc->length));
@@ -898,7 +890,7 @@ void hyperstone_device::generate_sequence_instruction(drcuml_block &block, compi
}
else
{
- UML_MOV(block, mem(&m_core->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_core->arg0), desc->opptr[0]);
UML_CALLC(block, &c_funcs::unimplemented, this);
}
}
@@ -908,7 +900,7 @@ void hyperstone_device::generate_sequence_instruction(drcuml_block &block, compi
bool hyperstone_device::generate_opcode(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc)
{
- uint32_t op = (uint32_t)desc->opptr.w[0];
+ uint32_t op = (uint32_t)desc->opptr[0];
switch (op >> 8)
{
diff --git a/src/devices/cpu/e132xs/e132xsdrc_ops.hxx b/src/devices/cpu/e132xs/e132xsdrc_ops.hxx
index bc8675fa7c9..ee3cce9b584 100644
--- a/src/devices/cpu/e132xs/e132xsdrc_ops.hxx
+++ b/src/devices/cpu/e132xs/e132xsdrc_ops.hxx
@@ -37,7 +37,7 @@ uint32_t hyperstone_device::generate_get_const(const opcode_desc *desc)
uint32_t hyperstone_device::generate_get_immediate_s(const opcode_desc *desc)
{
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
switch (op & 0xf)
{
@@ -56,7 +56,7 @@ uint32_t hyperstone_device::generate_get_immediate_s(const opcode_desc *desc)
uint32_t hyperstone_device::generate_get_pcrel(const opcode_desc *desc)
{
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
if (op & 0x80)
{
@@ -332,7 +332,7 @@ uml::parameter hyperstone_device::generate_load_address_ad(drcuml_block &block,
{
return 0;
}
- else if ((code == PC_REGISTER) && ((desc->flags & OPFLAG_IN_DELAY_SLOT) || !compiler.check_delay()))
+ else if ((code == PC_REGISTER) && (desc->in_delay_slot() || !compiler.check_delay()))
{
if (!compiler.pc())
generate_raise_exception(block, compiler, desc, TRAPNO_POINTER_ERROR);
@@ -578,7 +578,7 @@ void hyperstone_device::generate_update_nz_d(drcuml_block &block, compiler_state
void hyperstone_device::generate_raise_exception(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint8_t trapno, uml::parameter sr)
{
- if (desc->flags & OPFLAG_IN_DELAY_SLOT)
+ if (desc->in_delay_slot())
{
// definitely in delay slot - saved PC/ILC reflect delayed branch
UML_OR(block, sr, sr, P_MASK);
@@ -684,7 +684,7 @@ inline void hyperstone_device::generate_logic_op(drcuml_block &block, compiler_s
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t dst_code = (op & 0xf0) >> 4;
const uint32_t src_code = op & 0xf;
@@ -751,7 +751,7 @@ void hyperstone_device::generate_software(drcuml_block &block, compiler_state &c
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_6));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t num = op >> 8;
const uint32_t src_code = op & 0xf;
@@ -830,7 +830,7 @@ void hyperstone_device::generate_chk(drcuml_block &block, compiler_state &compil
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t src_code = op & 0xf;
const uint32_t dst_code = (op & 0xf0) >> 4;
@@ -891,7 +891,7 @@ void hyperstone_device::generate_movd(drcuml_block &block, compiler_state &compi
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_2));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t src_code = op & 0xf;
const uint32_t srcf_code = src_code + 1;
@@ -1048,7 +1048,7 @@ void hyperstone_device::generate_divsu(drcuml_block &block, compiler_state &comp
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_36));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t dst_code = (op & 0xf0) >> 4;
const uint32_t dstf_code = dst_code + 1;
@@ -1131,7 +1131,7 @@ void hyperstone_device::generate_xm(drcuml_block &block, compiler_state &compile
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t dst_code = (op & 0xf0) >> 4;
const uint32_t src_code = op & 0xf;
@@ -1179,7 +1179,7 @@ void hyperstone_device::generate_mask(drcuml_block &block, compiler_state &compi
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t src_code = op & 0xf;
const uint32_t dst_code = (op & 0xf0) >> 4;
@@ -1205,7 +1205,7 @@ void hyperstone_device::generate_sum(drcuml_block &block, compiler_state &compil
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t src_code = op & 0xf;
const uint32_t dst_code = (op & 0xf0) >> 4;
@@ -1215,7 +1215,7 @@ void hyperstone_device::generate_sum(drcuml_block &block, compiler_state &compil
if (!SrcGlobal || !DstGlobal)
UML_BFXU(block, I3, I2, FP_SHIFT, 7);
- if (SrcGlobal && (src_code == PC_REGISTER) && ((desc->flags & OPFLAG_IN_DELAY_SLOT) || !compiler.check_delay()))
+ if (SrcGlobal && (src_code == PC_REGISTER) && (desc->in_delay_slot() || !compiler.check_delay()))
{
const uint64_t result = uint64_t(compiler.pc()) + src;
const uint32_t flags =
@@ -1248,7 +1248,7 @@ void hyperstone_device::generate_sums(drcuml_block &block, compiler_state &compi
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t src_code = op & 0xf;
const uint32_t dst_code = (op & 0xf0) >> 4;
@@ -1289,7 +1289,7 @@ void hyperstone_device::generate_cmp(drcuml_block &block, compiler_state &compil
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t src_code = op & 0xf;
const uint32_t dst_code = (op & 0xf0) >> 4;
@@ -1311,7 +1311,7 @@ void hyperstone_device::generate_mov(drcuml_block &block, compiler_state &compil
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t src_code = op & 0xf;
const uint32_t dst_code = (op & 0xf0) >> 4;
@@ -1431,7 +1431,7 @@ void hyperstone_device::generate_add(drcuml_block &block, compiler_state &compil
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t src_code = op & 0xf;
const uint32_t dst_code = (op & 0xf0) >> 4;
@@ -1439,7 +1439,7 @@ void hyperstone_device::generate_add(drcuml_block &block, compiler_state &compil
if (!SrcGlobal || !DstGlobal)
UML_BFXU(block, I3, I2, FP_SHIFT, 7);
- if ((desc->flags & OPFLAG_IN_DELAY_SLOT) || !compiler.check_delay())
+ if (desc->in_delay_slot() || !compiler.check_delay())
{
const bool srcpc = SrcGlobal && (src_code == PC_REGISTER);
const bool dstpc = DstGlobal && (dst_code == PC_REGISTER);
@@ -1507,7 +1507,7 @@ void hyperstone_device::generate_adds(drcuml_block &block, compiler_state &compi
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t src_code = op & 0xf;
const uint32_t dst_code = (op & 0xf0) >> 4;
@@ -1547,7 +1547,7 @@ void hyperstone_device::generate_cmpb(drcuml_block &block, compiler_state &compi
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t src_code = op & 0xf;
const uint32_t dst_code = (op & 0xf0) >> 4;
@@ -1568,7 +1568,7 @@ void hyperstone_device::generate_subc(drcuml_block &block, compiler_state &compi
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t src_code = op & 0xf;
const uint32_t dst_code = (op & 0xf0) >> 4;
@@ -1601,7 +1601,7 @@ void hyperstone_device::generate_sub(drcuml_block &block, compiler_state &compil
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t src_code = op & 0xf;
const uint32_t dst_code = (op & 0xf0) >> 4;
@@ -1626,7 +1626,7 @@ void hyperstone_device::generate_subs(drcuml_block &block, compiler_state &compi
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t src_code = op & 0xf;
const uint32_t dst_code = (op & 0xf0) >> 4;
@@ -1666,7 +1666,7 @@ void hyperstone_device::generate_addc(drcuml_block &block, compiler_state &compi
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t src_code = op & 0xf;
const uint32_t dst_code = (op & 0xf0) >> 4;
@@ -1699,7 +1699,7 @@ void hyperstone_device::generate_neg(drcuml_block &block, compiler_state &compil
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t dst_code = (op & 0xf0) >> 4;
const uint32_t src_code = op & 0xf;
@@ -1723,7 +1723,7 @@ void hyperstone_device::generate_negs(drcuml_block &block, compiler_state &compi
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t dst_code = (op & 0xf0) >> 4;
const uint32_t src_code = op & 0xf;
@@ -1821,7 +1821,7 @@ void hyperstone_device::generate_not(drcuml_block &block, compiler_state &compil
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t dst_code = (op & 0xf0) >> 4;
const uint32_t src_code = op & 0xf;
@@ -1845,7 +1845,7 @@ void hyperstone_device::generate_cmpi(drcuml_block &block, compiler_state &compi
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t dst_code = (op & 0xf0) >> 4;
uint32_t src;
@@ -1872,7 +1872,7 @@ void hyperstone_device::generate_movi(drcuml_block &block, compiler_state &compi
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t dst_code = (op & 0xf0) >> 4;
uint32_t src;
@@ -1956,7 +1956,7 @@ void hyperstone_device::generate_addi(drcuml_block &block, compiler_state &compi
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t dst_code = (op & 0xf0) >> 4;
const bool roundeven = !(op & 0x10f);
@@ -1970,7 +1970,7 @@ void hyperstone_device::generate_addi(drcuml_block &block, compiler_state &compi
if (!DstGlobal)
UML_BFXU(block, I3, I2, FP_SHIFT, 7);
- if (DstGlobal && (dst_code == PC_REGISTER) && ((desc->flags & OPFLAG_IN_DELAY_SLOT) || !compiler.check_delay()))
+ if (DstGlobal && (dst_code == PC_REGISTER) && (desc->in_delay_slot() || !compiler.check_delay()))
{
uint64_t result;
uint32_t flags;
@@ -2034,7 +2034,7 @@ void hyperstone_device::generate_cmpbi(drcuml_block &block, compiler_state &comp
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t dst_code = (op & 0xf0) >> 4;
const uint32_t n = ((op & 0x100) >> 4) | (op & 0x0f);
@@ -2092,7 +2092,7 @@ void hyperstone_device::generate_andni(drcuml_block &block, compiler_state &comp
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
uint32_t src;
if (DRC_N_OP_MASK == 0x10f)
@@ -2117,7 +2117,7 @@ void hyperstone_device::generate_ori(drcuml_block &block, compiler_state &compil
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
uint32_t src;
if (ImmLong)
@@ -2139,7 +2139,7 @@ void hyperstone_device::generate_xori(drcuml_block &block, compiler_state &compi
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
uint32_t src;
if (ImmLong)
@@ -2161,7 +2161,7 @@ void hyperstone_device::generate_shrdi(drcuml_block &block, compiler_state &comp
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_2));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t dst_code = (op & 0xf0) >> 4;
const uint32_t n = HiN ? DRC_HI_N_VALUE : DRC_LO_N_VALUE;
@@ -2195,7 +2195,7 @@ void hyperstone_device::generate_shrd(drcuml_block &block, compiler_state &compi
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_2));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t src_code = op & 0xf;
const uint32_t dst_code = (op & 0xf0) >> 4;
@@ -2238,7 +2238,7 @@ void hyperstone_device::generate_shr(drcuml_block &block, compiler_state &compil
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t dst_code = (op & 0xf0) >> 4;
const uint32_t src_code = op & 0xf;
@@ -2270,7 +2270,7 @@ void hyperstone_device::generate_shri(drcuml_block &block, compiler_state &compi
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t dst_code = (op & 0xf0) >> 4;
const uint32_t n = HiN ? DRC_HI_N_VALUE : DRC_LO_N_VALUE;
@@ -2300,7 +2300,7 @@ void hyperstone_device::generate_sardi(drcuml_block &block, compiler_state &comp
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_2));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t dst_code = (op & 0xf0) >> 4;
const uint32_t n = HiN ? DRC_HI_N_VALUE : DRC_LO_N_VALUE;
@@ -2334,7 +2334,7 @@ void hyperstone_device::generate_sard(drcuml_block &block, compiler_state &compi
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_2));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t src_code = op & 0xf;
const uint32_t dst_code = (op & 0xf0) >> 4;
@@ -2377,7 +2377,7 @@ void hyperstone_device::generate_sar(drcuml_block &block, compiler_state &compil
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t dst_code = (op & 0xf0) >> 4;
const uint32_t src_code = op & 0xf;
@@ -2409,7 +2409,7 @@ void hyperstone_device::generate_sari(drcuml_block &block, compiler_state &compi
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t dst_code = (op & 0xf0) >> 4;
const uint32_t n = HiN ? DRC_HI_N_VALUE : DRC_LO_N_VALUE;
@@ -2439,7 +2439,7 @@ void hyperstone_device::generate_shldi(drcuml_block &block, compiler_state &comp
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_2));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t dst_code = (op & 0xf0) >> 4;
const uint32_t n = HiN ? DRC_HI_N_VALUE : DRC_LO_N_VALUE;
@@ -2488,7 +2488,7 @@ void hyperstone_device::generate_shld(drcuml_block &block, compiler_state &compi
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_2));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t src_code = op & 0xf;
const uint32_t dst_code = (op & 0xf0) >> 4;
@@ -2544,7 +2544,7 @@ void hyperstone_device::generate_shl(drcuml_block &block, compiler_state &compil
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t dst_code = (op & 0xf0) >> 4;
const uint32_t src_code = op & 0xf;
@@ -2593,7 +2593,7 @@ void hyperstone_device::generate_shli(drcuml_block &block, compiler_state &compi
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t dst_code = (op & 0xf0) >> 4;
const uint32_t n = HiN ? DRC_HI_N_VALUE : DRC_LO_N_VALUE;
@@ -2637,7 +2637,7 @@ void hyperstone_device::generate_testlz(drcuml_block &block, compiler_state &com
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_2));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t dst_code = (op & 0xf0) >> 4;
const uint32_t src_code = op & 0xf;
@@ -2655,7 +2655,7 @@ void hyperstone_device::generate_rol(drcuml_block &block, compiler_state &compil
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t dst_code = (op & 0xf0) >> 4;
const uint32_t src_code = op & 0xf;
@@ -2702,7 +2702,7 @@ void hyperstone_device::generate_rol(drcuml_block &block, compiler_state &compil
template <hyperstone_device::reg_bank DstGlobal, hyperstone_device::reg_bank SrcGlobal>
void hyperstone_device::generate_ldxx1(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc)
{
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t src_code = op & 0xf;
const uint32_t srcf_code = src_code + 1;
const uint32_t dst_code = (op & 0xf0) >> 4;
@@ -2845,7 +2845,7 @@ void hyperstone_device::generate_ldxx1(drcuml_block &block, compiler_state &comp
template <hyperstone_device::reg_bank DstGlobal, hyperstone_device::reg_bank SrcGlobal>
void hyperstone_device::generate_ldxx2(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc)
{
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t src_code = op & 0xf;
const uint32_t srcf_code = src_code + 1;
const uint32_t dst_code = (op & 0xf0) >> 4;
@@ -2994,7 +2994,7 @@ void hyperstone_device::generate_ldxx2(drcuml_block &block, compiler_state &comp
template <hyperstone_device::reg_bank DstGlobal, hyperstone_device::reg_bank SrcGlobal>
void hyperstone_device::generate_stxx1(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc)
{
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t src_code = op & 0xf;
const uint32_t dst_code = (op & 0xf0) >> 4;
@@ -3121,7 +3121,7 @@ void hyperstone_device::generate_stxx1(drcuml_block &block, compiler_state &comp
template <hyperstone_device::reg_bank DstGlobal, hyperstone_device::reg_bank SrcGlobal>
void hyperstone_device::generate_stxx2(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc)
{
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t src_code = op & 0xf;
const uint32_t dst_code = (op & 0xf0) >> 4;
@@ -3280,7 +3280,7 @@ void hyperstone_device::generate_mulsu(drcuml_block &block, compiler_state &comp
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_36));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t dst_code = (op & 0xf0) >> 4;
const uint32_t dstf_code = dst_code + 1;
const uint32_t src_code = op & 0xf;
@@ -3349,7 +3349,7 @@ void hyperstone_device::generate_mulsu(drcuml_block &block, compiler_state &comp
template <hyperstone_device::reg_bank DstGlobal, hyperstone_device::reg_bank SrcGlobal>
void hyperstone_device::generate_mul(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc)
{
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t src_code = op & 0xf;
const uint32_t dst_code = (op & 0xf0) >> 4;
@@ -3399,7 +3399,7 @@ void hyperstone_device::generate_set(drcuml_block &block, compiler_state &compil
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t dst_code = (op & 0xf0) >> 4;
const uint32_t n = op & 0xf;
@@ -3479,7 +3479,7 @@ void hyperstone_device::generate_ldwr(drcuml_block &block, compiler_state &compi
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t src_code = op & 0xf;
const uint32_t dst_code = (op & 0xf0) >> 4;
@@ -3504,7 +3504,7 @@ void hyperstone_device::generate_lddr(drcuml_block &block, compiler_state &compi
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_2));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t src_code = op & 0xf;
const uint32_t dst_code = (op & 0xf0) >> 4;
@@ -3550,7 +3550,7 @@ void hyperstone_device::generate_ldwp(drcuml_block &block, compiler_state &compi
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t src_code = op & 0xf;
const uint32_t dst_code = (op & 0xf0) >> 4;
@@ -3582,7 +3582,7 @@ void hyperstone_device::generate_lddp(drcuml_block &block, compiler_state &compi
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_2));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t src_code = op & 0xf;
const uint32_t dst_code = (op & 0xf0) >> 4;
@@ -3634,7 +3634,7 @@ void hyperstone_device::generate_stwr(drcuml_block &block, compiler_state &compi
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t src_code = op & 0xf;
const uint32_t dst_code = (op & 0xf0) >> 4;
@@ -3668,7 +3668,7 @@ void hyperstone_device::generate_stdr(drcuml_block &block, compiler_state &compi
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_2));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t src_code = op & 0xf;
const uint32_t dst_code = (op & 0xf0) >> 4;
@@ -3719,7 +3719,7 @@ void hyperstone_device::generate_stwp(drcuml_block &block, compiler_state &compi
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t src_code = op & 0xf;
const uint32_t dst_code = (op & 0xf0) >> 4;
@@ -3764,7 +3764,7 @@ void hyperstone_device::generate_stdp(drcuml_block &block, compiler_state &compi
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_2));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t src_code = op & 0xf;
const uint32_t dst_code = (op & 0xf0) >> 4;
@@ -3928,14 +3928,14 @@ void hyperstone_device::generate_dbr(drcuml_block &block, compiler_state &compil
{
UML_MOV(block, mem(&m_core->delay_slot_taken), 0);
generate_update_cycles(block);
- if (desc->flags & OPFLAG_INTRABLOCK_BRANCH)
+ if (desc->intrablock_branch())
UML_JMP(block, desc->targetpc | 0x80000000);
else
UML_HASHJMP(block, compiler.mode(), desc->targetpc, *m_nocode);
}
else
{
- UML_MOV(block, mem(&m_core->arg0), delayslot->opptr.w[0]);
+ UML_MOV(block, mem(&m_core->arg0), delayslot->opptr[0]);
UML_CALLC(block, &c_funcs::unimplemented, this);
}
}
@@ -3948,7 +3948,7 @@ void hyperstone_device::generate_frame(drcuml_block &block, compiler_state &comp
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t dst_code = (op & 0xf0) >> 4;
UML_MOV(block, I2, DRC_SR); // I2 = SR
@@ -3995,7 +3995,7 @@ void hyperstone_device::generate_call(drcuml_block &block, compiler_state &compi
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
UML_ROLINS(block, DRC_SR, ((desc->length >> 1) << ILC_SHIFT) | P_MASK, 0, ILC_MASK | P_MASK);
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
uint16_t imm_1 = m_pr16(desc->pc + 2);
int32_t extra_s = 0;
@@ -4079,7 +4079,7 @@ void hyperstone_device::generate_trap_op(drcuml_block &block, compiler_state &co
false, false, false, false, true, false, true, false, true, false, true, false, true, false, true, false
};
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint8_t trapno = (op & 0xfc) >> 2;
const uint8_t code = ((op & 0x300) >> 6) | (op & 0x03);
@@ -4101,7 +4101,7 @@ void hyperstone_device::generate_extend(drcuml_block &block, compiler_state &com
{
UML_MOV(block, I7, mem(&m_core->clock_cycles_1));
- const uint16_t op = desc->opptr.w[0];
+ const uint16_t op = desc->opptr[0];
const uint32_t src_code = op & 0xf;
const uint32_t dst_code = (op & 0xf0) >> 4;
diff --git a/src/devices/cpu/e132xs/e132xsfe.cpp b/src/devices/cpu/e132xs/e132xsfe.cpp
index 729bdad1a9f..87d9f0f36d1 100644
--- a/src/devices/cpu/e132xs/e132xsfe.cpp
+++ b/src/devices/cpu/e132xs/e132xsfe.cpp
@@ -10,38 +10,55 @@
#include "emu.h"
#include "e132xsfe.h"
+
#include "32xsdefs.h"
+#include "cpu/drcfe.ipp"
+
+
#define FE_DST_CODE ((op & 0xf0) >> 4)
#define FE_SRC_CODE (op & 0x0f)
-#define SR_CODE (1 << 1)
+#define SR_CODE (1)
+#define G_CODE_BASE (0)
+
/***************************************************************************
INSTRUCTION PARSERS
***************************************************************************/
-e132xs_frontend::e132xs_frontend(hyperstone_device &cpu, uint32_t window_start, uint32_t window_end, uint32_t max_sequence)
- : drc_frontend(cpu, window_start, window_end, max_sequence)
+hyperstone_device::frontend::frontend(hyperstone_device &cpu, uint32_t window_start, uint32_t window_end, uint32_t max_sequence)
+ : drc_frontend_base(cpu.space_config(AS_PROGRAM)->page_shift(), window_start, window_end, max_sequence)
, m_cpu(cpu)
{
}
-inline uint16_t e132xs_frontend::read_word(opcode_desc &desc)
+hyperstone_device::frontend::~frontend()
+{
+}
+
+hyperstone_device::opcode_desc const *hyperstone_device::frontend::describe_code(offs_t startpc)
+{
+ return do_describe_code(
+ [this] (opcode_desc &desc, opcode_desc const *prev) { return describe(desc, prev); },
+ startpc);
+}
+
+inline uint16_t hyperstone_device::frontend::read_word(opcode_desc &desc)
{
- return m_cpu.m_pr16(desc.physpc);
+ return m_cpu.m_pr16(desc.pc);
}
-inline uint16_t e132xs_frontend::read_imm1(opcode_desc &desc)
+inline uint16_t hyperstone_device::frontend::read_imm1(opcode_desc &desc)
{
- return m_cpu.m_pr16(desc.physpc + 2);
+ return m_cpu.m_pr16(desc.pc + 2);
}
-inline uint16_t e132xs_frontend::read_imm2(opcode_desc &desc)
+inline uint16_t hyperstone_device::frontend::read_imm2(opcode_desc &desc)
{
- return m_cpu.m_pr16(desc.physpc + 4);
+ return m_cpu.m_pr16(desc.pc + 4);
}
-inline uint32_t e132xs_frontend::read_ldstxx_imm(opcode_desc &desc)
+inline uint32_t hyperstone_device::frontend::read_ldstxx_imm(opcode_desc &desc)
{
const uint16_t imm1 = read_imm1(desc);
uint32_t extra_s;
@@ -63,7 +80,7 @@ inline uint32_t e132xs_frontend::read_ldstxx_imm(opcode_desc &desc)
return extra_s;
}
-inline uint32_t e132xs_frontend::read_limm(opcode_desc &desc, uint16_t op)
+inline uint32_t hyperstone_device::frontend::read_limm(opcode_desc &desc, uint16_t op)
{
static const int32_t immediate_values[16] =
{
@@ -88,7 +105,7 @@ inline uint32_t e132xs_frontend::read_limm(opcode_desc &desc, uint16_t op)
}
}
-inline int32_t e132xs_frontend::decode_pcrel(opcode_desc &desc, uint16_t op)
+inline int32_t hyperstone_device::frontend::decode_pcrel(opcode_desc &desc, uint16_t op)
{
if (op & 0x80)
{
@@ -111,7 +128,7 @@ inline int32_t e132xs_frontend::decode_pcrel(opcode_desc &desc, uint16_t op)
}
}
-inline int32_t e132xs_frontend::decode_call(opcode_desc &desc)
+inline int32_t hyperstone_device::frontend::decode_call(opcode_desc &desc)
{
const uint16_t imm_1 = read_imm1(desc);
int32_t extra_s = 0;
@@ -140,9 +157,9 @@ inline int32_t e132xs_frontend::decode_call(opcode_desc &desc)
instruction
-------------------------------------------------*/
-bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
+bool hyperstone_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev)
{
- uint16_t op = desc.opptr.w[0] = read_word(desc);
+ uint16_t op = desc.opptr[0] = read_word(desc);
/* most instructions are 2 bytes and a single cycle */
desc.length = 2;
@@ -156,295 +173,306 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
switch (op >> 8)
{
case 0x00: // chk global,global
- desc.regin[0] |= 1 << gdst_code;
- desc.regin[0] |= 1 << gsrc_code;
- desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.regin.set(G_CODE_BASE + gdst_code);
+ desc.regin.set(G_CODE_BASE + gsrc_code);
+ desc.set_can_cause_exception();
break;
case 0x01: // chk global,local
- desc.regin[0] |= SR_CODE;
- desc.regin[0] |= 1 << gdst_code;
- desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.regin.set(SR_CODE);
+ desc.regin.set(G_CODE_BASE + gdst_code);
+ desc.set_can_cause_exception();
break;
case 0x02: // chk local,global
- desc.regin[0] |= SR_CODE;
- desc.regin[0] |= 1 << gsrc_code;
- desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.regin.set(SR_CODE);
+ desc.regin.set(G_CODE_BASE + gsrc_code);
+ desc.set_can_cause_exception();
break;
case 0x03: // chk local,local
- desc.regin[0] |= SR_CODE;
- desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.regin.set(SR_CODE);
+ desc.set_can_cause_exception();
break;
case 0x04: // movd global,global
- desc.regin[0] |= 1 << gsrc_code;
- desc.regin[0] |= 1 << gsrcf_code;
- desc.regout[0] |= 1 << gdst_code;
- desc.regout[0] |= 1 << gdstf_code;
+ desc.regin.set(G_CODE_BASE + gsrc_code);
+ desc.regin.set(G_CODE_BASE + gsrcf_code);
+ desc.regout.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(G_CODE_BASE + gdstf_code);
if (gdst_code == PC_REGISTER)
{
desc.targetpc = BRANCH_TARGET_DYNAMIC;
- desc.flags |= OPFLAG_READS_MEMORY | OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE | OPFLAG_CAN_CAUSE_EXCEPTION | OPFLAG_CAN_CHANGE_MODES;
+ desc.set_is_unconditional_branch();
+ desc.set_can_cause_exception();
+ desc.set_end_sequence();
+ desc.set_can_change_modes();
+ desc.set_reads_memory();
}
- desc.regout[0] |= SR_CODE;
+ desc.regout.set(SR_CODE);
break;
case 0x05: // movd global,local
- desc.regin[0] |= SR_CODE;
- desc.regout[0] |= 1 << gdst_code;
- desc.regout[0] |= 1 << gdstf_code;
+ desc.regin.set(SR_CODE);
+ desc.regout.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(G_CODE_BASE + gdstf_code);
if (gdst_code == 0)
{
desc.targetpc = BRANCH_TARGET_DYNAMIC;
- desc.flags |= OPFLAG_READS_MEMORY | OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE | OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.set_is_unconditional_branch();
+ desc.set_can_cause_exception();
+ desc.set_end_sequence();
+ desc.set_reads_memory();
}
- desc.regout[0] |= SR_CODE;
+ desc.regout.set(SR_CODE);
break;
case 0x06: // movd local,global
- desc.regin[0] |= SR_CODE;
- desc.regin[0] |= 1 << gsrc_code;
- desc.regin[0] |= 1 << gsrcf_code;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regin.set(G_CODE_BASE + gsrc_code);
+ desc.regin.set(G_CODE_BASE + gsrcf_code);
+ desc.regout.set(SR_CODE);
break;
case 0x07: // movd local,local
- desc.regin[0] |= SR_CODE;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regout.set(SR_CODE);
break;
case 0x08: // divu global,global
case 0x0c: // divs global,global
- desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
- desc.regin[0] |= 1 << gsrc_code;
- desc.regin[0] |= 1 << gdst_code;
- desc.regin[0] |= 1 << gdstf_code;
- desc.regout[0] |= 1 << gdst_code;
- desc.regout[0] |= 1 << gdstf_code;
- desc.regout[0] |= SR_CODE;
+ desc.set_can_cause_exception();
+ desc.regin.set(G_CODE_BASE + gsrc_code);
+ desc.regin.set(G_CODE_BASE + gdst_code);
+ desc.regin.set(G_CODE_BASE + gdstf_code);
+ desc.regout.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(G_CODE_BASE + gdstf_code);
+ desc.regout.set(SR_CODE);
break;
case 0x09: // divu global,local
case 0x0d: // divs global,local
- desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
- desc.regin[0] |= SR_CODE;
- desc.regin[0] |= 1 << gdst_code;
- desc.regin[0] |= 1 << gdstf_code;
- desc.regout[0] |= 1 << gdst_code;
- desc.regout[0] |= 1 << gdstf_code;
- desc.regout[0] |= SR_CODE;
+ desc.set_can_cause_exception();
+ desc.regin.set(SR_CODE);
+ desc.regin.set(G_CODE_BASE + gdst_code);
+ desc.regin.set(G_CODE_BASE + gdstf_code);
+ desc.regout.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(G_CODE_BASE + gdstf_code);
+ desc.regout.set(SR_CODE);
break;
case 0x0a: // divu local,global
case 0x0e: // divs local,global
- desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
- desc.regin[0] |= SR_CODE;
- desc.regin[0] |= 1 << gsrc_code;
- desc.regout[0] |= SR_CODE;
+ desc.set_can_cause_exception();
+ desc.regin.set(SR_CODE);
+ desc.regin.set(G_CODE_BASE + gsrc_code);
+ desc.regout.set(SR_CODE);
break;
case 0x0b: // divu local,local
case 0x0f: // divs local,local
- desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
- desc.regin[0] |= SR_CODE;
- desc.regout[0] |= SR_CODE;
+ desc.set_can_cause_exception();
+ desc.regin.set(SR_CODE);
+ desc.regout.set(SR_CODE);
break;
case 0x10: // xm global,global
- desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
- desc.regin[0] |= 1 << gsrc_code;
- desc.regout[0] |= 1 << gdst_code;
+ desc.set_can_cause_exception();
+ desc.regin.set(G_CODE_BASE + gsrc_code);
+ desc.regout.set(G_CODE_BASE + gdst_code);
desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4;
break;
case 0x11: // xm global,local
- desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
- desc.regin[0] |= SR_CODE;
- desc.regout[0] |= 1 << gdst_code;
+ desc.set_can_cause_exception();
+ desc.regin.set(SR_CODE);
+ desc.regout.set(G_CODE_BASE + gdst_code);
desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4;
break;
case 0x12: // xm local,global
- desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
- desc.regin[0] |= SR_CODE;
- desc.regin[0] |= 1 << gsrc_code;
+ desc.set_can_cause_exception();
+ desc.regin.set(SR_CODE);
+ desc.regin.set(G_CODE_BASE + gsrc_code);
desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4;
break;
case 0x13: // xm local,local
- desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
- desc.regin[0] |= SR_CODE;
+ desc.set_can_cause_exception();
+ desc.regin.set(SR_CODE);
desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4;
break;
case 0x14: // mask global,global
- desc.regin[0] |= 1 << gsrc_code;
- desc.regout[0] |= 1 << gdst_code;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(G_CODE_BASE + gsrc_code);
+ desc.regout.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(SR_CODE);
desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4;
break;
case 0x15: // mask global,local
- desc.regin[0] |= SR_CODE;
- desc.regout[0] |= 1 << gdst_code;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regout.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(SR_CODE);
desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4;
break;
case 0x16: // mask local,global
- desc.regin[0] |= SR_CODE;
- desc.regin[0] |= 1 << gsrc_code;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regin.set(G_CODE_BASE + gsrc_code);
+ desc.regout.set(SR_CODE);
desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4;
break;
case 0x17: // mask local,local
- desc.regin[0] |= SR_CODE;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regout.set(SR_CODE);
desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4;
break;
case 0x18: // sum global,global
case 0x1c: // sums global,global
- desc.regin[0] |= 1 << gsrc_code;
- desc.regout[0] |= 1 << gdst_code;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(G_CODE_BASE + gsrc_code);
+ desc.regout.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(SR_CODE);
desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4;
- if (op & 0x4 && gsrc_code != SR_REGISTER) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
+ if (op & 0x4 && gsrc_code != SR_REGISTER) desc.set_can_cause_exception();
break;
case 0x19: // sum global,local
case 0x1d: // sums global,local
- desc.regin[0] |= SR_CODE;
- desc.regout[0] |= 1 << gdst_code;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regout.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(SR_CODE);
desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4;
- if (op & 0x4) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
+ if (op & 0x4) desc.set_can_cause_exception();
break;
case 0x1a: // sum local,global
case 0x1e: // sums local,global
- desc.regin[0] |= SR_CODE;
- desc.regin[0] |= 1 << gsrc_code;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regin.set(G_CODE_BASE + gsrc_code);
+ desc.regout.set(SR_CODE);
desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4;
- if (op & 0x4 && gsrc_code != SR_REGISTER) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
+ if (op & 0x4 && gsrc_code != SR_REGISTER) desc.set_can_cause_exception();
break;
case 0x1b: // sum local,local
case 0x1f: // sums local,local
- desc.regin[0] |= SR_CODE;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regout.set(SR_CODE);
desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4;
- if (op & 0x4) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
+ if (op & 0x4) desc.set_can_cause_exception();
break;
case 0x20: // cmp global,global
case 0x30: // cmpb global,global
- desc.regin[0] |= 1 << gsrc_code;
- desc.regin[0] |= 1 << gdst_code;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(G_CODE_BASE + gsrc_code);
+ desc.regin.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(SR_CODE);
break;
case 0x21: // cmp global,local
case 0x31: // cmpb global,local
- desc.regin[0] |= SR_CODE;
- desc.regin[0] |= 1 << gdst_code;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regin.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(SR_CODE);
break;
case 0x22: // cmp local,global
case 0x32: // cmpb local,global
- desc.regin[0] |= SR_CODE;
- desc.regin[0] |= 1 << gsrc_code;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regin.set(G_CODE_BASE + gsrc_code);
+ desc.regout.set(SR_CODE);
break;
case 0x23: // cmp local,local
case 0x33: // cmpb local,local
- desc.regin[0] |= SR_CODE;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regout.set(SR_CODE);
break;
case 0x24: // mov global,global
- desc.regin[0] |= SR_CODE;
- desc.regin[0] |= 1 << gsrc_code;
- desc.regin[0] |= 1 << (gsrc_code + 16);
- desc.regout[0] |= 1 << gdst_code;
- desc.regout[0] |= SR_CODE;
- desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.regin.set(SR_CODE);
+ desc.regin.set(G_CODE_BASE + gsrc_code);
+ desc.regin.set(G_CODE_BASE + gsrc_code + 16);
+ desc.regout.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(SR_CODE);
+ desc.set_can_cause_exception();
if (gdst_code == PC_REGISTER)
{
if (gsrc_code != PC_REGISTER)
desc.targetpc = BRANCH_TARGET_DYNAMIC;
else
- desc.targetpc = desc.physpc + desc.length;
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.targetpc = desc.pc + desc.length;
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
}
else if (gdst_code == 5) // TPR_REGISTER & 0xf
{
- desc.flags |= OPFLAG_END_SEQUENCE;
+ desc.set_end_sequence();
}
break;
case 0x25: // mov global,local
- desc.regin[0] |= SR_CODE;
- desc.regout[0] |= 1 << gdst_code;
- desc.regout[0] |= SR_CODE;
- desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.regin.set(SR_CODE);
+ desc.regout.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(SR_CODE);
+ desc.set_can_cause_exception();
if (gdst_code == PC_REGISTER)
{
desc.targetpc = BRANCH_TARGET_DYNAMIC;
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
}
else if (gdst_code == 5) // TPR_REGISTER & 0xf
{
- desc.flags |= OPFLAG_END_SEQUENCE;
+ desc.set_end_sequence();
}
break;
case 0x26: // mov local,global
- desc.regin[0] |= SR_CODE;
- desc.regin[0] |= 1 << gsrc_code;
- desc.regin[0] |= 1 << (gsrc_code + 16);
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regin.set(G_CODE_BASE + gsrc_code);
+ desc.regin.set(G_CODE_BASE + gsrc_code + 16);
+ desc.regout.set(SR_CODE);
break;
case 0x27: // mov local,local
- desc.regin[0] |= SR_CODE;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regout.set(SR_CODE);
break;
case 0x28: // add global,global
case 0x2c: // adds global,global
case 0x48: // sub global,global
case 0x4c: // subs global,global
- desc.regin[0] |= 1 << gsrc_code;
- desc.regin[0] |= 1 << gdst_code;
- desc.regout[0] |= 1 << gdst_code;
- desc.regout[0] |= SR_CODE;
- if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // adds, subs
+ desc.regin.set(G_CODE_BASE + gsrc_code);
+ desc.regin.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(SR_CODE);
+ if (op & 0x04) desc.set_can_cause_exception(); // adds, subs
if (gdst_code == PC_REGISTER)
{
if (gsrc_code != PC_REGISTER)
desc.targetpc = BRANCH_TARGET_DYNAMIC;
else if (((op >> 8) == 0x28) || ((op >> 8) == 0x2c))
- desc.targetpc = (desc.physpc + desc.length) << 1;
+ desc.targetpc = (desc.pc + desc.length) << 1;
else
desc.targetpc = 0;
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
}
break;
case 0x29: // add global,local
case 0x2d: // adds global,local
case 0x49: // sub global,local
case 0x4d: // subs global,local
- desc.regin[0] |= SR_CODE;
- desc.regin[0] |= 1 << gdst_code;
- desc.regout[0] |= 1 << gdst_code;
- desc.regout[0] |= SR_CODE;
- if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // adds, subs
+ desc.regin.set(SR_CODE);
+ desc.regin.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(SR_CODE);
+ if (op & 0x04) desc.set_can_cause_exception(); // adds, subs
if (gdst_code == PC_REGISTER)
{
desc.targetpc = BRANCH_TARGET_DYNAMIC;
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
}
break;
case 0x2a: // add local,global
case 0x2e: // adds local,global
case 0x4a: // sub local,global
case 0x4e: // subs local,global
- desc.regin[0] |= SR_CODE;
- desc.regin[0] |= 1 << gsrc_code;
- desc.regout[0] |= SR_CODE;
- if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // adds, subs
+ desc.regin.set(SR_CODE);
+ desc.regin.set(G_CODE_BASE + gsrc_code);
+ desc.regout.set(SR_CODE);
+ if (op & 0x04) desc.set_can_cause_exception(); // adds, subs
break;
case 0x2b: // add local,local
case 0x2f: // adds local,local
case 0x4b: // sub local,local
case 0x4f: // subs local,local
- desc.regin[0] |= SR_CODE;
- desc.regout[0] |= SR_CODE;
- if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // adds, subs
+ desc.regin.set(SR_CODE);
+ desc.regout.set(SR_CODE);
+ if (op & 0x04) desc.set_can_cause_exception(); // adds, subs
break;
case 0x34: // andn global,global
case 0x38: // or global,global
case 0x3c: // xor global,global
case 0x54: // and global,global
- desc.regin[0] |= 1 << gsrc_code;
- desc.regin[0] |= 1 << gdst_code;
- desc.regout[0] |= 1 << gdst_code;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(G_CODE_BASE + gsrc_code);
+ desc.regin.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(SR_CODE);
if (gdst_code == PC_REGISTER)
{
if (gsrc_code != PC_REGISTER)
@@ -452,374 +480,393 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
else if (((op >> 8) == 0x34) || ((op >> 8) == 0x3c))
desc.targetpc = 0;
else
- desc.targetpc = desc.physpc + desc.length;
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.targetpc = desc.pc + desc.length;
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
}
break;
case 0x35: // andn global,local
case 0x39: // or global,local
case 0x3d: // xor global,local
case 0x55: // and global,local
- desc.regin[0] |= SR_CODE;
- desc.regin[0] |= 1 << gdst_code;
- desc.regout[0] |= 1 << gdst_code;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regin.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(SR_CODE);
if (gdst_code == PC_REGISTER)
{
desc.targetpc = BRANCH_TARGET_DYNAMIC;
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
}
break;
case 0x36: // andn local,global
case 0x3a: // or local,global
case 0x3e: // xor local,global
case 0x56: // and local,global
- desc.regin[0] |= SR_CODE;
- desc.regin[0] |= 1 << gsrc_code;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regin.set(G_CODE_BASE + gsrc_code);
+ desc.regout.set(SR_CODE);
break;
case 0x37: // andn local,local
case 0x3b: // or local,local
case 0x3f: // xor local,local
case 0x57: // and local,local
- desc.regin[0] |= SR_CODE;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regout.set(SR_CODE);
break;
case 0x40: // subc global,global
case 0x50: // addc global,global
- desc.regin[0] |= SR_CODE;
- desc.regin[0] |= 1 << gsrc_code;
- desc.regin[0] |= 1 << gdst_code;
- desc.regout[0] |= 1 << gdst_code;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regin.set(G_CODE_BASE + gsrc_code);
+ desc.regin.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(SR_CODE);
if (gdst_code == PC_REGISTER)
{
desc.targetpc = BRANCH_TARGET_DYNAMIC;
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
}
break;
case 0x41: // subc global,local
case 0x51: // addc global,local
- desc.regin[0] |= SR_CODE;
- desc.regin[0] |= 1 << gdst_code;
- desc.regout[0] |= 1 << gdst_code;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regin.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(SR_CODE);
if (gdst_code == PC_REGISTER)
{
desc.targetpc = BRANCH_TARGET_DYNAMIC;
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
}
break;
case 0x42: // subc local,global
case 0x52: // addc local,global
- desc.regin[0] |= SR_CODE;
- desc.regin[0] |= 1 << gsrc_code;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regin.set(G_CODE_BASE + gsrc_code);
+ desc.regout.set(SR_CODE);
break;
case 0x43: // subc local,local
case 0x53: // addc local,local
- desc.regin[0] |= SR_CODE;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regout.set(SR_CODE);
break;
case 0x44: // not global,global
case 0x58: // neg global,global
- desc.regin[0] |= 1 << gsrc_code;
- desc.regout[0] |= 1 << gdst_code;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(G_CODE_BASE + gsrc_code);
+ desc.regout.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(SR_CODE);
if (gdst_code == PC_REGISTER)
{
if (gsrc_code != PC_REGISTER)
desc.targetpc = BRANCH_TARGET_DYNAMIC;
else if ((op >> 8) == 0x44)
- desc.targetpc = ~uint32_t(desc.physpc + desc.length) & ~uint32_t(1);
+ desc.targetpc = ~uint32_t(desc.pc + desc.length) & ~uint32_t(1);
else
- desc.targetpc = uint32_t(-int32_t(desc.physpc + desc.length)) & ~uint32_t(1);
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.targetpc = uint32_t(-int32_t(desc.pc + desc.length)) & ~uint32_t(1);
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
}
break;
case 0x45: // not global,local
case 0x59: // neg global,local
- desc.regin[0] |= SR_CODE;
- desc.regout[0] |= 1 << gdst_code;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regout.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(SR_CODE);
if (gdst_code == PC_REGISTER)
{
desc.targetpc = BRANCH_TARGET_DYNAMIC;
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
}
break;
case 0x46: // not local,global
case 0x5a: // neg local,global
- desc.regin[0] |= SR_CODE;
- desc.regin[0] |= 1 << gsrc_code;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regin.set(G_CODE_BASE + gsrc_code);
+ desc.regout.set(SR_CODE);
break;
case 0x47: // not local,local
case 0x5b: // neg local,local
- desc.regin[0] |= SR_CODE;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regout.set(SR_CODE);
break;
case 0x5c: // negs global,global
- desc.regin[0] |= 1 << gsrc_code;
- desc.regout[0] |= 1 << gdst_code;
- desc.regout[0] |= SR_CODE;
- desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.regin.set(G_CODE_BASE + gsrc_code);
+ desc.regout.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(SR_CODE);
+ desc.set_can_cause_exception();
if (gdst_code == PC_REGISTER)
{
if (gsrc_code != PC_REGISTER)
desc.targetpc = BRANCH_TARGET_DYNAMIC;
else
- desc.targetpc = uint32_t(-int32_t(desc.physpc + desc.length)) & ~uint32_t(1);
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.targetpc = uint32_t(-int32_t(desc.pc + desc.length)) & ~uint32_t(1);
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
}
break;
case 0x5d: // negs global,local
- desc.regin[0] |= SR_CODE;
- desc.regout[0] |= 1 << gdst_code;
- desc.regout[0] |= SR_CODE;
- desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.regin.set(SR_CODE);
+ desc.regout.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(SR_CODE);
+ desc.set_can_cause_exception();
if (gdst_code == PC_REGISTER)
{
desc.targetpc = BRANCH_TARGET_DYNAMIC;
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
}
break;
case 0x5e: // negs local,global
- desc.regin[0] |= SR_CODE;
- desc.regin[0] |= 1 << gsrc_code;
- desc.regout[0] |= SR_CODE;
- desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.regin.set(SR_CODE);
+ desc.regin.set(G_CODE_BASE + gsrc_code);
+ desc.regout.set(SR_CODE);
+ desc.set_can_cause_exception();
break;
case 0x5f: // negs local,local
- desc.regin[0] |= SR_CODE;
- desc.regout[0] |= SR_CODE;
- desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.regin.set(SR_CODE);
+ desc.regout.set(SR_CODE);
+ desc.set_can_cause_exception();
break;
case 0x60: // cmpi global,simm
case 0x70: // cmpbi global,simm
- desc.regout[0] |= 1 << gdst_code;
- desc.regout[0] |= SR_CODE;
+ desc.regout.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(SR_CODE);
break;
case 0x61: // cmpi global,limm
case 0x71: // cmpbi global,limm
- desc.regout[0] |= 1 << gdst_code;
- desc.regout[0] |= SR_CODE;
+ desc.regout.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(SR_CODE);
desc.length = hyperstone_device::imm_length(op) << 1;
break;
case 0x62: // cmpi local,simm
case 0x72: // cmpbi local,simm
- desc.regin[0] |= SR_CODE;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regout.set(SR_CODE);
break;
case 0x63: // cmpi local,limm
case 0x73: // cmpbi local,limm
- desc.regin[0] |= SR_CODE;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regout.set(SR_CODE);
desc.length = hyperstone_device::imm_length(op) << 1;
break;
case 0x64: // movi global,simm
- desc.regin[0] |= SR_CODE;
- desc.regout[0] |= 1 << gdst_code;
- desc.regout[0] |= 1 << (gdst_code + 16);
- desc.regout[0] |= SR_CODE;
- desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.regin.set(SR_CODE);
+ desc.regout.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(G_CODE_BASE + gdst_code + 16);
+ desc.regout.set(SR_CODE);
+ desc.set_can_cause_exception();
if (gdst_code == PC_REGISTER)
{
desc.targetpc = op & 0xe;
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
}
else if (gdst_code == 5) // TPR_REGISTER & 0xf
{
- desc.flags |= OPFLAG_END_SEQUENCE;
+ desc.set_end_sequence();
}
break;
case 0x65: // movi global,limm
- desc.regin[0] |= SR_CODE;
- desc.regout[0] |= 1 << gdst_code;
- desc.regout[0] |= 1 << (gdst_code + 16);
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regout.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(G_CODE_BASE + gdst_code + 16);
+ desc.regout.set(SR_CODE);
desc.length = hyperstone_device::imm_length(op) << 1;
- desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.set_can_cause_exception();
if (gdst_code == PC_REGISTER)
{
desc.targetpc = read_limm(desc, op) & ~uint32_t(1);
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
}
else if (gdst_code == 5) // TPR_REGISTER & 0xf
{
- desc.flags |= OPFLAG_END_SEQUENCE;
+ desc.set_end_sequence();
}
break;
case 0x66: // movi local,simm
- desc.regin[0] |= SR_CODE;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regout.set(SR_CODE);
break;
case 0x67: // movi local,limm
- desc.regin[0] |= SR_CODE;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regout.set(SR_CODE);
desc.length = hyperstone_device::imm_length(op) << 1;
break;
case 0x68: // addi global,simm
case 0x6c: // addsi global,simm
- desc.regin[0] |= SR_CODE;
- desc.regin[0] |= 1 << gdst_code;
- desc.regout[0] |= 1 << gdst_code;
- desc.regout[0] |= SR_CODE;
- if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // addsi
+ desc.regin.set(SR_CODE);
+ desc.regin.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(SR_CODE);
+ if (op & 0x04) desc.set_can_cause_exception(); // addsi
if (gdst_code == PC_REGISTER)
{
- desc.targetpc = desc.physpc + desc.length + (op & 0xe);
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.targetpc = desc.pc + desc.length + (op & 0xe);
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
}
break;
case 0x69: // addi global,limm
case 0x6d: // addsi global,limm
- desc.regin[0] |= SR_CODE;
- desc.regin[0] |= 1 << gdst_code;
- desc.regout[0] |= 1 << gdst_code;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regin.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(SR_CODE);
desc.length = hyperstone_device::imm_length(op) << 1;
- if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // addsi
+ if (op & 0x04) desc.set_can_cause_exception(); // addsi
if (gdst_code == PC_REGISTER)
{
desc.targetpc = desc.pc + desc.length + (read_limm(desc, op) & ~uint32_t(1));
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
}
break;
case 0x6a: // addi local,simm
case 0x6e: // addsi local,simm
- desc.regin[0] |= SR_CODE;
- desc.regout[0] |= SR_CODE;
- if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // addsi
+ desc.regin.set(SR_CODE);
+ desc.regout.set(SR_CODE);
+ if (op & 0x04) desc.set_can_cause_exception(); // addsi
break;
case 0x6b: // addi local,limm
case 0x6f: // addsi local,limm
- desc.regin[0] |= SR_CODE;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regout.set(SR_CODE);
desc.length = hyperstone_device::imm_length(op) << 1;
- if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // addsi
+ if (op & 0x04) desc.set_can_cause_exception(); // addsi
break;
case 0x74: // andni global,simm
- desc.regin[0] |= SR_CODE;
- desc.regin[0] |= 1 << gdst_code;
- desc.regout[0] |= 1 << gdst_code;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regin.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(SR_CODE);
if (gdst_code == PC_REGISTER)
{
- desc.targetpc = (desc.physpc + desc.length) & ~uint32_t(op & 0xf);
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.targetpc = (desc.pc + desc.length) & ~uint32_t(op & 0xf);
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
}
break;
case 0x78: // ori global,simm
- desc.regin[0] |= SR_CODE;
- desc.regin[0] |= 1 << gdst_code;
- desc.regout[0] |= 1 << gdst_code;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regin.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(SR_CODE);
if (gdst_code == PC_REGISTER)
{
- desc.targetpc = (desc.physpc + desc.length) | (op & 0xe);
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.targetpc = (desc.pc + desc.length) | (op & 0xe);
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
}
break;
case 0x7c: // xori global,simm
- desc.regin[0] |= SR_CODE;
- desc.regin[0] |= 1 << gdst_code;
- desc.regout[0] |= 1 << gdst_code;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regin.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(SR_CODE);
if (gdst_code == PC_REGISTER)
{
- desc.targetpc = (desc.physpc + desc.length) ^ (op & 0xe);
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.targetpc = (desc.pc + desc.length) ^ (op & 0xe);
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
}
break;
case 0x75: // andni global,limm
- desc.regin[0] |= SR_CODE;
- desc.regin[0] |= 1 << gdst_code;
- desc.regout[0] |= 1 << gdst_code;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regin.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(SR_CODE);
desc.length = hyperstone_device::imm_length(op) << 1;
if (gdst_code == PC_REGISTER)
{
- desc.targetpc = (desc.physpc + desc.length) & ~read_limm(desc, op);
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.targetpc = (desc.pc + desc.length) & ~read_limm(desc, op);
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
}
break;
case 0x79: // ori global,limm
- desc.regin[0] |= SR_CODE;
- desc.regin[0] |= 1 << gdst_code;
- desc.regout[0] |= 1 << gdst_code;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regin.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(SR_CODE);
desc.length = hyperstone_device::imm_length(op) << 1;
if (gdst_code == PC_REGISTER)
{
- desc.targetpc = (desc.physpc + desc.length) | (read_limm(desc, op) & ~uint32_t(1));
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.targetpc = (desc.pc + desc.length) | (read_limm(desc, op) & ~uint32_t(1));
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
}
break;
case 0x7d: // xori global,limm
- desc.regin[0] |= SR_CODE;
- desc.regin[0] |= 1 << gdst_code;
- desc.regout[0] |= 1 << gdst_code;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regin.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(SR_CODE);
desc.length = hyperstone_device::imm_length(op) << 1;
if (gdst_code == PC_REGISTER)
{
- desc.targetpc = (desc.physpc + desc.length) ^ (read_limm(desc, op) & ~uint32_t(1));
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.targetpc = (desc.pc + desc.length) ^ (read_limm(desc, op) & ~uint32_t(1));
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
}
break;
case 0x76: // andni local,simm
case 0x7a: // ori local,simm
case 0x7e: // xori local,simm
- desc.regin[0] |= SR_CODE;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regout.set(SR_CODE);
break;
case 0x77: // andni local,limm
case 0x7b: // ori local,limm
case 0x7f: // xori local,limm
- desc.regin[0] |= SR_CODE;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regout.set(SR_CODE);
desc.length = hyperstone_device::imm_length(op) << 1;
break;
case 0x80: case 0x81: // shrdi
case 0x84: case 0x85: // sardi
case 0x88: case 0x89: // shldi
- desc.regin[0] |= SR_CODE;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regout.set(SR_CODE);
break;
case 0x82: // shrd
case 0x86: // sard
case 0x8a: // shld
- desc.regin[0] |= SR_CODE;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regout.set(SR_CODE);
break;
case 0x83: // shr
case 0x87: // sar
case 0x8b: // shl
case 0x8f: // rol
- desc.regin[0] |= SR_CODE;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regout.set(SR_CODE);
break;
case 0x8c: case 0x8d: // reserved
return false;
case 0x8e: // testlz
- desc.regin[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
break;
case 0x90: // ldxx1 global,global
{
const uint16_t imm1 = read_imm1(desc);
const uint32_t extra_s = read_ldstxx_imm(desc);
- desc.regin[0] |= 1 << gdst_code;
- desc.regout[0] |= 1 << gsrc_code;
- if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regout[0] |= 1 << gsrcf_code;
+ desc.regin.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(G_CODE_BASE + gsrc_code);
+ if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regout.set(G_CODE_BASE + gsrcf_code);
desc.length = (imm1 & 0x8000) ? 6 : 4;
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_reads_memory();
if (gdst_code == PC_REGISTER)
{
desc.targetpc = BRANCH_TARGET_DYNAMIC;
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
}
break;
}
@@ -828,15 +875,16 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
const uint16_t imm1 = read_imm1(desc);
[[maybe_unused]] const uint32_t extra_s = read_ldstxx_imm(desc);
- desc.regin[0] |= SR_CODE;
- desc.regin[0] |= 1 << gdst_code;
+ desc.regin.set(SR_CODE);
+ desc.regin.set(G_CODE_BASE + gdst_code);
desc.length = (imm1 & 0x8000) ? 6 : 4;
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_reads_memory();
if (gdst_code == PC_REGISTER)
{
desc.targetpc = BRANCH_TARGET_DYNAMIC;
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
}
break;
}
@@ -845,12 +893,12 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
const uint16_t imm1 = read_imm1(desc);
const uint32_t extra_s = read_ldstxx_imm(desc);
- desc.regin[0] |= SR_CODE;
- desc.regout[0] |= 1 << gsrc_code;
- if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regout[0] |= 1 << gsrcf_code;
+ desc.regin.set(SR_CODE);
+ desc.regout.set(G_CODE_BASE + gsrc_code);
+ if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regout.set(G_CODE_BASE + gsrcf_code);
desc.length = (imm1 & 0x8000) ? 6 : 4;
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_reads_memory();
break;
}
case 0x93: // ldxx1 local,local
@@ -858,10 +906,10 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
const uint16_t imm1 = read_imm1(desc);
[[maybe_unused]] const uint32_t extra_s = read_ldstxx_imm(desc);
- desc.regin[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
desc.length = (imm1 & 0x8000) ? 6 : 4;
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_reads_memory();
break;
}
case 0x94: // ldxx2 global,global
@@ -869,17 +917,18 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
const uint16_t imm1 = read_imm1(desc);
const uint32_t extra_s = read_ldstxx_imm(desc);
- desc.regin[0] |= 1 << gdst_code;
- desc.regout[0] |= 1 << gdst_code;
- desc.regout[0] |= 1 << gsrc_code;
- if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regout[0] |= 1 << gsrcf_code;
+ desc.regin.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(G_CODE_BASE + gsrc_code);
+ if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regout.set(G_CODE_BASE + gsrcf_code);
desc.length = (imm1 & 0x8000) ? 6 : 4;
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_reads_memory();
if (gdst_code == PC_REGISTER)
{
desc.targetpc = BRANCH_TARGET_DYNAMIC;
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
}
break;
}
@@ -888,16 +937,17 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
const uint16_t imm1 = read_imm1(desc);
[[maybe_unused]] const uint32_t extra_s = read_ldstxx_imm(desc);
- desc.regin[0] |= SR_CODE;
- desc.regin[0] |= 1 << gdst_code;
- desc.regout[0] |= 1 << gdst_code;
+ desc.regin.set(SR_CODE);
+ desc.regin.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(G_CODE_BASE + gdst_code);
desc.length = (imm1 & 0x8000) ? 6 : 4;
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_reads_memory();
if (gdst_code == PC_REGISTER)
{
desc.targetpc = BRANCH_TARGET_DYNAMIC;
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
}
break;
}
@@ -906,12 +956,12 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
const uint16_t imm1 = read_imm1(desc);
const uint32_t extra_s = read_ldstxx_imm(desc);
- desc.regin[0] |= SR_CODE;
- desc.regout[0] |= 1 << gsrc_code;
- if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regout[0] |= 1 << gsrcf_code;
+ desc.regin.set(SR_CODE);
+ desc.regout.set(G_CODE_BASE + gsrc_code);
+ if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regout.set(G_CODE_BASE + gsrcf_code);
desc.length = (imm1 & 0x8000) ? 6 : 4;
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_reads_memory();
break;
}
case 0x97: // ldxx2 local,local
@@ -919,10 +969,10 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
const uint16_t imm1 = read_imm1(desc);
[[maybe_unused]] const uint32_t extra_s = read_ldstxx_imm(desc);
- desc.regin[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
desc.length = (imm1 & 0x8000) ? 6 : 4;
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_reads_memory();
break;
}
case 0x98: // stxx1 global,global
@@ -930,12 +980,12 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
const uint16_t imm1 = read_imm1(desc);
const uint32_t extra_s = read_ldstxx_imm(desc);
- desc.regin[0] |= 1 << gdst_code;
- desc.regin[0] |= 1 << gsrc_code;
- if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regin[0] |= 1 << gsrcf_code;
+ desc.regin.set(G_CODE_BASE + gdst_code);
+ desc.regin.set(G_CODE_BASE + gsrc_code);
+ if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regin.set(G_CODE_BASE + gsrcf_code);
desc.length = (imm1 & 0x8000) ? 6 : 4;
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_writes_memory();
break;
}
case 0x99: // stxx1 global,local
@@ -943,11 +993,11 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
const uint16_t imm1 = read_imm1(desc);
[[maybe_unused]] const uint32_t extra_s = read_ldstxx_imm(desc);
- desc.regin[0] |= SR_CODE;
- desc.regin[0] |= 1 << gdst_code;
+ desc.regin.set(SR_CODE);
+ desc.regin.set(G_CODE_BASE + gdst_code);
desc.length = (imm1 & 0x8000) ? 6 : 4;
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_writes_memory();
break;
}
case 0x9a: // stxx1 local,global
@@ -955,12 +1005,12 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
const uint16_t imm1 = read_imm1(desc);
const uint32_t extra_s = read_ldstxx_imm(desc);
- desc.regin[0] |= SR_CODE;
- desc.regin[0] |= 1 << gsrc_code;
- if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regin[0] |= 1 << gsrcf_code;
+ desc.regin.set(SR_CODE);
+ desc.regin.set(G_CODE_BASE + gsrc_code);
+ if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regin.set(G_CODE_BASE + gsrcf_code);
desc.length = (imm1 & 0x8000) ? 6 : 4;
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_writes_memory();
break;
}
case 0x9b: // stxx1 local,local
@@ -968,10 +1018,10 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
const uint16_t imm1 = read_imm1(desc);
[[maybe_unused]] const uint32_t extra_s = read_ldstxx_imm(desc);
- desc.regin[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
desc.length = (imm1 & 0x8000) ? 6 : 4;
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_writes_memory();
break;
}
case 0x9c: // stxx2 global,global
@@ -979,13 +1029,13 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
const uint16_t imm1 = read_imm1(desc);
const uint32_t extra_s = read_ldstxx_imm(desc);
- desc.regin[0] |= 1 << gdst_code;
- desc.regin[0] |= 1 << gsrc_code;
- if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regin[0] |= 1 << gsrcf_code;
- desc.regout[0] |= 1 << gdst_code;
+ desc.regin.set(G_CODE_BASE + gdst_code);
+ desc.regin.set(G_CODE_BASE + gsrc_code);
+ if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regin.set(G_CODE_BASE + gsrcf_code);
+ desc.regout.set(G_CODE_BASE + gdst_code);
desc.length = (imm1 & 0x8000) ? 6 : 4;
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_writes_memory();
break;
}
case 0x9d: // stxx2 global,local
@@ -993,12 +1043,12 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
const uint16_t imm1 = read_imm1(desc);
[[maybe_unused]] const uint32_t extra_s = read_ldstxx_imm(desc);
- desc.regin[0] |= SR_CODE;
- desc.regin[0] |= 1 << gdst_code;
- desc.regout[0] |= 1 << gdst_code;
+ desc.regin.set(SR_CODE);
+ desc.regin.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(G_CODE_BASE + gdst_code);
desc.length = (imm1 & 0x8000) ? 6 : 4;
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_writes_memory();
break;
}
case 0x9e: // stxx2 local,global
@@ -1006,12 +1056,12 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
const uint16_t imm1 = read_imm1(desc);
const uint32_t extra_s = read_ldstxx_imm(desc);
- desc.regin[0] |= SR_CODE;
- desc.regin[0] |= 1 << gsrc_code;
- if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regin[0] |= 1 << gsrcf_code;
+ desc.regin.set(SR_CODE);
+ desc.regin.set(G_CODE_BASE + gsrc_code);
+ if ((imm1 & 0x3000) == 0x3000 && (extra_s & 2)) desc.regin.set(G_CODE_BASE + gsrcf_code);
desc.length = (imm1 & 0x8000) ? 6 : 4;
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_writes_memory();
break;
}
case 0x9f: // stxx2 local,local
@@ -1019,10 +1069,10 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
const uint16_t imm1 = read_imm1(desc);
[[maybe_unused]] const uint32_t extra_s = read_ldstxx_imm(desc);
- desc.regin[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
desc.length = (imm1 & 0x8000) ? 6 : 4;
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_writes_memory();
break;
}
case 0xa0: // shri global (lo n)
@@ -1031,9 +1081,9 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
case 0xa5: // sari global (hi n)
case 0xa8: // shli global (lo n)
case 0xa9: // shli global (hi n)
- desc.regin[0] |= 1 << gdst_code;
- desc.regout[0] |= 1 << gdst_code;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(SR_CODE);
break;
case 0xa2: // shri local (lo n)
case 0xa3: // shri local (hi n)
@@ -1041,183 +1091,197 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
case 0xa7: // sari local (hi n)
case 0xaa: // shli local (lo n)
case 0xab: // shli local (hi n)
- desc.regin[0] |= SR_CODE;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regout.set(SR_CODE);
break;
case 0xac: case 0xad: case 0xae: case 0xaf: // reserved
return false;
case 0xb0: // mulu global,global
case 0xb4: // muls global,global
- desc.regin[0] |= 1 << gsrc_code;
- desc.regin[0] |= 1 << gdst_code;
- desc.regout[0] |= 1 << gdst_code;
- desc.regout[0] |= 1 << gdstf_code;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(G_CODE_BASE + gsrc_code);
+ desc.regin.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(G_CODE_BASE + gdstf_code);
+ desc.regout.set(SR_CODE);
break;
case 0xb1: // mulu global,local
case 0xb5: // muls global,local
- desc.regin[0] |= 1 << gdst_code;
- desc.regout[0] |= 1 << gdst_code;
- desc.regout[0] |= 1 << gdstf_code;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(G_CODE_BASE + gdstf_code);
+ desc.regout.set(SR_CODE);
break;
case 0xb2: // mulu local,global
case 0xb6: // muls local,global
- desc.regin[0] |= 1 << gsrc_code;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(G_CODE_BASE + gsrc_code);
+ desc.regout.set(SR_CODE);
break;
case 0xb3: // mulu local,local
case 0xb7: // muls local,local
- desc.regout[0] |= SR_CODE;
+ desc.regout.set(SR_CODE);
break;
case 0xb8: // set global (lo n)
case 0xb9: // set global (hi n)
- desc.regin[0] |= SR_CODE;
- desc.regout[0] |= 1 << gdst_code;
+ desc.regin.set(SR_CODE);
+ desc.regout.set(G_CODE_BASE + gdst_code);
break;
case 0xba: // set local (lo n)
case 0xbb: // set local (hi n)
break;
case 0xbc: // mul global,global
- desc.regin[0] |= 1 << gsrc_code;
- desc.regin[0] |= 1 << gdst_code;
- desc.regout[0] |= 1 << gdst_code;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(G_CODE_BASE + gsrc_code);
+ desc.regin.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(SR_CODE);
break;
case 0xbd: // muls global,local
- desc.regin[0] |= 1 << gdst_code;
- desc.regout[0] |= 1 << gdst_code;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(G_CODE_BASE + gdst_code);
+ desc.regout.set(SR_CODE);
break;
case 0xbe: // muls local,global
- desc.regin[0] |= 1 << gsrc_code;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(G_CODE_BASE + gsrc_code);
+ desc.regout.set(SR_CODE);
break;
case 0xbf: // mulu local,local
- desc.regout[0] |= SR_CODE;
+ desc.regout.set(SR_CODE);
break;
case 0xc0: case 0xc1: case 0xc2: case 0xc3: // software
case 0xc4: case 0xc5: case 0xc6: case 0xc7: // software
case 0xc8: case 0xc9: case 0xca: case 0xcb: // software
case 0xcc: case 0xcd: // software
- desc.regin[0] |= SR_CODE;
- desc.regout[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
+ desc.regout.set(SR_CODE);
desc.targetpc = BRANCH_TARGET_DYNAMIC;
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE | OPFLAG_CAN_CHANGE_MODES;
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
+ desc.set_can_change_modes();
break;
case 0xce: // extend - 4 bytes
- desc.regin[0] |= SR_CODE;
- desc.regin[0] |= (3 << 14); // global regs 14, 15
- desc.regout[0] |= (3 << 14); // global regs 14, 15
+ desc.regin.set(SR_CODE);
+ desc.regin.set(G_CODE_BASE + 14); // global regs 14, 15
+ desc.regin.set(G_CODE_BASE + 15);
+ desc.regout.set(G_CODE_BASE + 14); // global regs 14, 15
+ desc.regout.set(G_CODE_BASE + 15);
desc.length = 4;
break;
case 0xcf: // do
return false;
case 0xd0: // ldwr global
case 0xd4: // ldwp global
- desc.regin[0] |= SR_CODE;
- desc.regout[0] |= 1 << gsrc_code;
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.regin.set(SR_CODE);
+ desc.regout.set(G_CODE_BASE + gsrc_code);
+ desc.set_reads_memory();
break;
case 0xd1: // ldwr local
case 0xd5: // ldwp local
- desc.regin[0] |= SR_CODE;
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.regin.set(SR_CODE);
+ desc.set_reads_memory();
break;
case 0xd2: // lddr global
case 0xd6: // lddp global
- desc.regin[0] |= SR_CODE;
- desc.regout[0] |= 1 << gsrc_code;
- desc.regout[0] |= 1 << gsrcf_code;
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.regin.set(SR_CODE);
+ desc.regout.set(G_CODE_BASE + gsrc_code);
+ desc.regout.set(G_CODE_BASE + gsrcf_code);
+ desc.set_reads_memory();
break;
case 0xd3: // lddr local
case 0xd7: // lddp local
- desc.regin[0] |= SR_CODE;
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.regin.set(SR_CODE);
+ desc.set_reads_memory();
break;
case 0xd8: // stwr global
case 0xdc: // stwp global
- desc.regin[0] |= SR_CODE;
- desc.regin[0] |= 1 << gsrc_code;
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.regin.set(SR_CODE);
+ desc.regin.set(G_CODE_BASE + gsrc_code);
+ desc.set_writes_memory();
break;
case 0xd9: // stwr local
case 0xdd: // stwp local
- desc.regin[0] |= SR_CODE;
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.regin.set(SR_CODE);
+ desc.set_writes_memory();
break;
case 0xda: // stdr global
case 0xde: // stdp global
- desc.regin[0] |= SR_CODE;
- desc.regin[0] |= 1 << gsrc_code;
- desc.regin[0] |= 1 << gsrcf_code;
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.regin.set(SR_CODE);
+ desc.regin.set(G_CODE_BASE + gsrc_code);
+ desc.regin.set(G_CODE_BASE + gsrcf_code);
+ desc.set_writes_memory();
break;
case 0xdb: // stdr local
case 0xdf: // stdp local
- desc.regin[0] |= SR_CODE;
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.regin.set(SR_CODE);
+ desc.set_writes_memory();
break;
case 0xe0: case 0xe1: case 0xe2: case 0xe3: // dbv, dbnv, dbe, dbne - could be 4 bytes (pcrel)
case 0xe4: case 0xe5: case 0xe6: case 0xe7: // dbc, dbnc, dbse, dbht - could be 4 bytes (pcrel)
case 0xe8: case 0xe9: case 0xea: case 0xeb: // dbn, dbnn, dblt, dbgt - could be 4 bytes (pcrel)
- desc.regin[0] |= SR_CODE;
- desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+ desc.regin.set(SR_CODE);
+ desc.set_is_conditional_branch();
desc.delayslots = 1;
desc.length = (op & 0x80) ? 4 : 2;
- desc.targetpc = desc.physpc + desc.length + decode_pcrel(desc, op);
+ desc.targetpc = desc.pc + desc.length + decode_pcrel(desc, op);
break;
case 0xec: // dbr
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
desc.delayslots = 1;
desc.length = (op & 0x80) ? 4 : 2;
- desc.targetpc = desc.physpc + desc.length + decode_pcrel(desc, op);
+ desc.targetpc = desc.pc + desc.length + decode_pcrel(desc, op);
break;
case 0xed: // frame
- desc.regin[0] |= SR_CODE;
- desc.regout[0] |= SR_CODE;
- desc.flags |= OPFLAG_WRITES_MEMORY | OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.regin.set(SR_CODE);
+ desc.regout.set(SR_CODE);
+ desc.set_writes_memory();
break;
case 0xee: // call global
- desc.regin[0] |= SR_CODE;
- desc.regin[0] |= 1 << gsrc_code;
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.regin.set(SR_CODE);
+ desc.regin.set(G_CODE_BASE + gsrc_code);
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4;
if (gsrc_code == PC_REGISTER)
- desc.targetpc = desc.physpc + desc.length + (decode_call(desc) & ~uint32_t(1));
+ desc.targetpc = desc.pc + desc.length + (decode_call(desc) & ~uint32_t(1));
else if (gsrc_code == SR_REGISTER)
desc.targetpc = decode_call(desc) & ~uint32_t(1);
else
desc.targetpc = BRANCH_TARGET_DYNAMIC;
break;
case 0xef: // call local
- desc.regin[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
desc.targetpc = BRANCH_TARGET_DYNAMIC;
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4;
break;
case 0xf0: case 0xf1: case 0xf2: case 0xf3: // bv, bnv, be, bne
case 0xf4: case 0xf5: case 0xf6: case 0xf7: // bc, bnc, bse, bht
case 0xf8: case 0xf9: case 0xfa: case 0xfb: // bn, bnn, blt, bgt
- desc.regin[0] |= SR_CODE;
- desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+ desc.regin.set(SR_CODE);
+ desc.set_is_conditional_branch();
desc.length = (op & 0x80) ? 4 : 2;
desc.targetpc = desc.pc + desc.length + decode_pcrel(desc, op);
break;
case 0xfc: // br
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
desc.length = (op & 0x80) ? 4 : 2;
desc.targetpc = desc.pc + desc.length + decode_pcrel(desc, op);
break;
case 0xfd: case 0xfe: case 0xff: // trap
- desc.regin[0] |= SR_CODE;
+ desc.regin.set(SR_CODE);
desc.targetpc = BRANCH_TARGET_DYNAMIC;
if ((((op & 0x300) >> 6) | (op & 0x03)) == 15)
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE | OPFLAG_CAN_CAUSE_EXCEPTION;
+ {
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
+ }
else
- desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH | OPFLAG_CAN_CAUSE_EXCEPTION;
+ {
+ desc.set_is_conditional_branch();
+ }
+ desc.set_can_cause_exception();
break;
}
return true;
diff --git a/src/devices/cpu/e132xs/e132xsfe.h b/src/devices/cpu/e132xs/e132xsfe.h
index c71849228e8..22dbf96c89c 100644
--- a/src/devices/cpu/e132xs/e132xsfe.h
+++ b/src/devices/cpu/e132xs/e132xsfe.h
@@ -6,19 +6,65 @@
#pragma once
#include "e132xs.h"
+
#include "cpu/drcfe.h"
-class e132xs_frontend : public drc_frontend
+#include <algorithm>
+#include <bitset>
+
+
+class hyperstone_device::opcode_desc : public opcode_desc_base<opcode_desc, 32>
{
public:
- e132xs_frontend(hyperstone_device &cpu, uint32_t window_start, uint32_t window_end, uint32_t max_sequence);
- void flush();
+ uint16_t opptr[3]; // copy of up to 3 halfwords of opcode
+
+ void set_can_change_modes() { m_extra_flags.set(CAN_CHANGE_MODES); }
+ void set_reads_memory() { m_extra_flags.set(READS_MEMORY); }
+ void set_writes_memory() { m_extra_flags.set(WRITES_MEMORY); }
+
+ bool can_change_modes() const { return m_extra_flags[CAN_CHANGE_MODES]; }
+ bool reads_memory() const { return m_extra_flags[READS_MEMORY]; }
+ bool writes_memory() const { return m_extra_flags[WRITES_MEMORY]; }
+
+ // epc - compute the exception PC
+ uint32_t epc() const
+ {
+ return in_delay_slot() ? branch->pc : pc;
+ }
+
+ void reset(offs_t curpc, bool in_delay_slot)
+ {
+ opcode_desc_base::reset(curpc, in_delay_slot);
+
+ std::fill(std::begin(opptr), std::end(opptr), 0);
+ m_extra_flags.reset();
+ }
protected:
- // required overrides
- virtual bool describe(opcode_desc &desc, const opcode_desc *prev) override;
+ enum
+ {
+ CAN_CHANGE_MODES = 0,
+ READS_MEMORY,
+ WRITES_MEMORY,
+
+ EXTRA_FLAG_COUNT
+ };
+
+ std::bitset<EXTRA_FLAG_COUNT> m_extra_flags;
+};
+
+
+class hyperstone_device::frontend : public drc_frontend_base<opcode_desc>
+{
+public:
+ frontend(hyperstone_device &cpu, uint32_t window_start, uint32_t window_end, uint32_t max_sequence);
+ ~frontend();
+
+ opcode_desc const *describe_code(offs_t startpc);
private:
+ bool describe(opcode_desc &desc, opcode_desc const *prev);
+
uint16_t read_word(opcode_desc &desc);
uint16_t read_imm1(opcode_desc &desc);
uint16_t read_imm2(opcode_desc &desc);
diff --git a/src/devices/cpu/mb86235/mb86235.h b/src/devices/cpu/mb86235/mb86235.h
index e3a660f1987..b7b9a830a0c 100644
--- a/src/devices/cpu/mb86235/mb86235.h
+++ b/src/devices/cpu/mb86235/mb86235.h
@@ -11,18 +11,13 @@
#pragma once
-#include "cpu/drcfe.h"
#include "cpu/drcuml.h"
#include "machine/gen_fifo.h"
-class mb86235_frontend;
-
class mb86235_device : public cpu_device
{
- friend class mb86235_frontend;
-
public:
// construction/destruction
mb86235_device(const machine_config &mconfig, const char *_tag, device_t *_owner, uint32_t clock);
@@ -64,23 +59,26 @@ public:
void internal_bbus(address_map &map) ATTR_COLD;
protected:
- // device-level overrides
+ class frontend;
+ class opcode_desc;
+
+ // device_t implementation
virtual void device_start() override ATTR_COLD;
virtual void device_reset() override ATTR_COLD;
- // device_execute_interface overrides
+ // device_execute_interface implementation
virtual uint32_t execute_min_cycles() const noexcept override { return 1; }
virtual uint32_t execute_max_cycles() const noexcept override { return 7; }
virtual void execute_run() override;
//virtual void execute_set_input(int inputnum, int state);
- // device_memory_interface overrides
+ // device_memory_interface implementation
virtual space_config_vector memory_space_config() const override;
- // device_state_interface overrides
+ // device_state_interface implementation
virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
- // device_disasm_interface overrides
+ // device_disasm_interface implementation
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
private:
@@ -178,7 +176,7 @@ private:
drc_cache m_cache;
std::unique_ptr<drcuml_state> m_drcuml;
- std::unique_ptr<mb86235_frontend> m_drcfe;
+ std::unique_ptr<frontend> m_drcfe;
memory_access<12, 3, -3, ENDIANNESS_LITTLE>::cache m_pcache;
memory_access<12, 3, -3, ENDIANNESS_LITTLE>::specific m_program;
diff --git a/src/devices/cpu/mb86235/mb86235defs.h b/src/devices/cpu/mb86235/mb86235defs.h
deleted file mode 100644
index 3156c239788..00000000000
--- a/src/devices/cpu/mb86235/mb86235defs.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef MAME_CPU_MB86235_MB86235DEFS_H
-#define MAME_CPU_MB86235_MB86235DEFS_H
-
-#pragma once
-
-
-#define OP_USERFLAG_FIFOIN 0x1
-#define OP_USERFLAG_FIFOOUT 0x2
-#define OP_USERFLAG_REPEAT 0x8
-#define OP_USERFLAG_REPEATED_OP 0x10
-#define OP_USERFLAG_PR_MASK 0x300
-#define OP_USERFLAG_PR_INC 0x100
-#define OP_USERFLAG_PR_DEC 0x200
-#define OP_USERFLAG_PR_ZERO 0x300
-#define OP_USERFLAG_PW_MASK 0xc00
-#define OP_USERFLAG_PW_INC 0x400
-#define OP_USERFLAG_PW_DEC 0x800
-#define OP_USERFLAG_PW_ZERO 0xc00
-
-#endif // MAME_CPU_MB86235_MB86235DEFS_H
diff --git a/src/devices/cpu/mb86235/mb86235drc.cpp b/src/devices/cpu/mb86235/mb86235drc.cpp
index 67e562c865a..cfad532e8c3 100644
--- a/src/devices/cpu/mb86235/mb86235drc.cpp
+++ b/src/devices/cpu/mb86235/mb86235drc.cpp
@@ -8,14 +8,11 @@
#include "emu.h"
#include "mb86235.h"
+
#include "mb86235fe.h"
-#include "cpu/drcfe.h"
-#include "cpu/drcuml.h"
#include "cpu/drcumlsh.h"
-#include "mb86235defs.h"
-
/*
TODO:
@@ -62,20 +59,20 @@
#define RPC uml::mem(&m_core->rpc)
#define LPC uml::mem(&m_core->lpc)
-#define AZ_CALC_REQUIRED ((desc->regreq[1] & 0x1) || desc->flags & OPFLAG_IN_DELAY_SLOT)
-#define AN_CALC_REQUIRED ((desc->regreq[1] & 0x2) || desc->flags & OPFLAG_IN_DELAY_SLOT)
-#define AV_CALC_REQUIRED ((desc->regreq[1] & 0x4) || desc->flags & OPFLAG_IN_DELAY_SLOT)
-#define AU_CALC_REQUIRED ((desc->regreq[1] & 0x8) || desc->flags & OPFLAG_IN_DELAY_SLOT)
-#define AD_CALC_REQUIRED ((desc->regreq[1] & 0x10) || desc->flags & OPFLAG_IN_DELAY_SLOT)
-#define ZC_CALC_REQUIRED ((desc->regreq[1] & 0x20) || desc->flags & OPFLAG_IN_DELAY_SLOT)
-#define IL_CALC_REQUIRED ((desc->regreq[1] & 0x40) || desc->flags & OPFLAG_IN_DELAY_SLOT)
-#define NR_CALC_REQUIRED ((desc->regreq[1] & 0x80) || desc->flags & OPFLAG_IN_DELAY_SLOT)
-#define ZD_CALC_REQUIRED ((desc->regreq[1] & 0x100) || desc->flags & OPFLAG_IN_DELAY_SLOT)
-#define MN_CALC_REQUIRED ((desc->regreq[1] & 0x200) || desc->flags & OPFLAG_IN_DELAY_SLOT)
-#define MZ_CALC_REQUIRED ((desc->regreq[1] & 0x400) || desc->flags & OPFLAG_IN_DELAY_SLOT)
-#define MV_CALC_REQUIRED ((desc->regreq[1] & 0x800) || desc->flags & OPFLAG_IN_DELAY_SLOT)
-#define MU_CALC_REQUIRED ((desc->regreq[1] & 0x1000) || desc->flags & OPFLAG_IN_DELAY_SLOT)
-#define MD_CALC_REQUIRED ((desc->regreq[1] & 0x2000) || desc->flags & OPFLAG_IN_DELAY_SLOT)
+#define AZ_CALC_REQUIRED (desc->az_calc_required())
+#define AN_CALC_REQUIRED (desc->an_calc_required())
+#define AV_CALC_REQUIRED (desc->av_calc_required())
+#define AU_CALC_REQUIRED (desc->au_calc_required())
+#define AD_CALC_REQUIRED (desc->ad_calc_required())
+#define ZC_CALC_REQUIRED (desc->zc_calc_required())
+#define IL_CALC_REQUIRED (desc->il_calc_required())
+#define NR_CALC_REQUIRED (desc->nr_calc_required())
+#define ZD_CALC_REQUIRED (desc->zd_calc_required())
+#define MN_CALC_REQUIRED (desc->mn_calc_required())
+#define MZ_CALC_REQUIRED (desc->mz_calc_required())
+#define MV_CALC_REQUIRED (desc->mv_calc_required())
+#define MU_CALC_REQUIRED (desc->mu_calc_required())
+#define MD_CALC_REQUIRED (desc->md_calc_required())
inline void mb86235_device::alloc_handle(uml::code_handle *&handleptr, const char *name)
{
@@ -267,7 +264,7 @@ void mb86235_device::compile_block(offs_t pc)
/* determine the last instruction in this sequence */
for (seqlast = seqhead; seqlast != nullptr; seqlast = seqlast->next())
- if (seqlast->flags & OPFLAG_END_SEQUENCE)
+ if (seqlast->end_sequence())
break;
assert(seqlast != nullptr);
@@ -292,7 +289,7 @@ void mb86235_device::compile_block(offs_t pc)
}
/* label this instruction, if it may be jumped to locally */
- if (seqhead->flags & OPFLAG_IS_BRANCH_TARGET)
+ if (seqhead->is_branch_target())
UML_LABEL(block, seqhead->pc | 0x80000000); // label seqhead->pc
/* iterate over instructions in the sequence and compile them */
@@ -300,7 +297,7 @@ void mb86235_device::compile_block(offs_t pc)
generate_sequence_instruction(block, compiler, curdesc);
/* if we need to return to the start, do it */
- if (seqlast->flags & OPFLAG_RETURN_TO_START)
+ if (seqlast->return_to_start())
nextpc = pc;
/* otherwise we just go to the next instruction */
else
@@ -497,14 +494,14 @@ void mb86235_device::flush_cache()
void mb86235_device::generate_sequence_instruction(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc)
{
/* add an entry for the log */
- // if (m_drcuml->logging() && !(desc->flags & OPFLAG_VIRTUAL_NOOP))
- // log_add_disasm_comment(block, desc->pc, desc->opptr.l[0]);
+ // if (m_drcuml->logging() && !desc->virtual_noop())
+ // 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
/* accumulate total cycles */
- compiler.cycles += desc->cycles;
+ compiler.cycles += 1;
/* update the icount map variable */
UML_MAPVAR(block, MAPVAR_CYCLES, compiler.cycles); // mapvar CYCLES,compiler.cycles
@@ -517,26 +514,18 @@ void mb86235_device::generate_sequence_instruction(drcuml_block &block, compiler
UML_DEBUG(block, desc->pc); // debug desc->pc
}
- /* if we hit an unmapped address, fatal error */
- if (desc->flags & OPFLAG_COMPILER_UNMAPPED)
- {
- UML_MOV(block, mem(&m_core->pc), desc->pc); // mov [pc],desc->pc
- save_fast_iregs(block); // <save fastregs>
- UML_EXIT(block, EXECUTE_UNMAPPED_CODE); // exit EXECUTE_UNMAPPED_CODE
- }
-
/* if this is an invalid opcode, generate the exception now */
- // if (desc->flags & OPFLAG_INVALID_OPCODE)
+ // if (desc->invalid_opcode())
// UML_EXH(block, *m_exception[EXCEPTION_PROGRAM], 0x80000); // exh exception_program,0x80000
/* unless this is a virtual no-op, it's a regular instruction */
- if (!(desc->flags & OPFLAG_VIRTUAL_NOOP))
+ if (!desc->virtual_noop())
{
/* 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.q[0]); // dmov [arg64],*desc->opptr.q
+ UML_DMOV(block, mem(&m_core->arg64), desc->opptr); // dmov [arg64],*desc->opptr
UML_CALLC(block, cfunc_unimplemented, this); // callc cfunc_unimplemented,ppc
}
}
@@ -724,19 +713,19 @@ bool mb86235_device::has_register_clash(const opcode_desc *desc, int outreg)
{
case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
// MA0-7
- if (desc->regin[0] & (1 << (16 + (outreg & 7)))) return true;
+ if (desc->ma_used(outreg & 7)) return true;
break;
case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
// MB0-7
- if (desc->regin[0] & (1 << (24 + (outreg & 7)))) return true;
+ if (desc->mb_used(outreg & 7)) return true;
break;
case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
// AA0-7
- if (desc->regin[0] & (1 << (outreg & 7))) return true;
+ if (desc->aa_used(outreg & 7)) return true;
break;
case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
// AB0-7
- if (desc->regin[0] & (1 << (8 + (outreg & 7)))) return true;
+ if (desc->ab_used(outreg & 7)) return true;
break;
}
return false;
@@ -761,26 +750,26 @@ bool mb86235_device::aluop_has_result(int aluop)
bool mb86235_device::generate_opcode(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc)
{
- uint64_t opcode = desc->opptr.q[0];
+ uint64_t opcode = desc->opptr;
bool fifoin_check = false;
bool fifoout_check = false;
// enable fifo in check if this opcode or the delay slot reads from FIFO
- if (desc->userflags & OP_USERFLAG_FIFOIN)
+ if (desc->fifoin())
fifoin_check = true;
if (desc->delayslots > 0)
{
- if (desc->delay.first()->userflags & OP_USERFLAG_FIFOIN)
+ if (desc->delay.first()->fifoin())
fifoin_check = true;
}
// enable fifo out check if this opcode or the delay slot writes to FIFO
- if (desc->userflags & OP_USERFLAG_FIFOOUT)
+ if (desc->fifoout())
fifoout_check = true;
if (desc->delayslots > 0)
{
- if (desc->delay.first()->userflags & OP_USERFLAG_FIFOOUT)
+ if (desc->delay.first()->fifoout())
fifoout_check = true;
}
@@ -912,48 +901,48 @@ bool mb86235_device::generate_opcode(drcuml_block &block, compiler_state &compil
}
// update PR and PW if needed
- if ((desc->userflags & OP_USERFLAG_PR_MASK) != 0)
+ if (desc->pr() != 0)
{
- switch ((desc->userflags & OP_USERFLAG_PR_MASK) >> 8)
+ switch (desc->pr())
{
- case 1: // PR++
+ case opcode_desc::INC: // PR++
UML_ADD(block, PRP, PRP, 1);
UML_CMP(block, PRP, 24);
UML_MOVc(block, COND_GE, PRP, 0);
break;
- case 2: // PR--
+ case opcode_desc::DEC: // PR--
UML_SUB(block, PRP, PRP, 1);
UML_CMP(block, PRP, 0);
UML_MOVc(block, COND_L, PRP, 23);
break;
- case 3: // PR#0
+ case opcode_desc::ZERO: // PR#0
UML_MOV(block, PRP, 0);
break;
}
}
- if ((desc->userflags & OP_USERFLAG_PW_MASK) != 0)
+ if (desc->pw() != 0)
{
- switch ((desc->userflags & OP_USERFLAG_PW_MASK) >> 10)
+ switch (desc->pw())
{
- case 1: // PW++
+ case opcode_desc::INC: // PW++
UML_ADD(block, PWP, PWP, 1);
UML_CMP(block, PWP, 24);
UML_MOVc(block, COND_GE, PWP, 0);
break;
- case 2: // PW--
+ case opcode_desc::DEC: // PW--
UML_SUB(block, PWP, PWP, 1);
UML_CMP(block, PWP, 0);
UML_MOVc(block, COND_L, PWP, 23);
break;
- case 3: // PW#0
+ case opcode_desc::ZERO: // PW#0
UML_MOV(block, PWP, 0);
break;
}
}
// handle repeat
- if (desc->userflags & OP_USERFLAG_REPEATED_OP)
+ if (desc->repeated_op())
{
uml::code_label const no_repeat = compiler.labelnum++;
UML_SUB(block, RPC, RPC, 1);
@@ -961,7 +950,7 @@ bool mb86235_device::generate_opcode(drcuml_block &block, compiler_state &compil
UML_JMPc(block, COND_LE, no_repeat);
generate_update_cycles(block, compiler, desc->pc, true);
- if (desc->flags & OPFLAG_INTRABLOCK_BRANCH)
+ if (desc->intrablock_branch())
UML_JMP(block, desc->pc | 0x80000000);
else
UML_HASHJMP(block, 0, desc->pc, *m_nocode);
@@ -1365,7 +1354,7 @@ void mb86235_device::generate_branch(drcuml_block &block, compiler_state &compil
if (desc->targetpc != BRANCH_TARGET_DYNAMIC)
{
generate_update_cycles(block, compiler_temp, desc->targetpc, true);
- if (desc->flags & OPFLAG_INTRABLOCK_BRANCH)
+ if (desc->intrablock_branch())
UML_JMP(block, desc->targetpc | 0x80000000); // jmp targetpc | 0x80000000
else
UML_HASHJMP(block, 0, desc->targetpc, *m_nocode); // hashjmp 0,targetpc,nocode
@@ -1484,7 +1473,7 @@ void mb86235_device::generate_condition(drcuml_block &block, compiler_state &com
void mb86235_device::generate_control(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc)
{
- uint64_t op = desc->opptr.q[0];
+ uint64_t op = desc->opptr;
int ef1 = (op >> 16) & 0x3f;
int ef2 = op & 0xffff;
int cop = (op >> 22) & 0x1f;
@@ -1593,7 +1582,7 @@ void mb86235_device::generate_control(drcuml_block &block, compiler_state &compi
void mb86235_device::generate_xfer1(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc)
{
- uint64_t opcode = desc->opptr.q[0];
+ uint64_t opcode = desc->opptr;
int dr = (opcode >> 12) & 0x7f;
int sr = (opcode >> 19) & 0x7f;
@@ -1657,13 +1646,13 @@ void mb86235_device::generate_xfer1(drcuml_block &block, compiler_state &compile
void mb86235_device::generate_double_xfer1(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc)
{
UML_MOV(block, mem(&m_core->pc), desc->pc);
- UML_DMOV(block, mem(&m_core->arg64), desc->opptr.q[0]);
+ UML_DMOV(block, mem(&m_core->arg64), desc->opptr);
UML_CALLC(block, cfunc_unimplemented_double_xfer1, this);
}
void mb86235_device::generate_xfer2(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc)
{
- uint64_t opcode = desc->opptr.q[0];
+ uint64_t opcode = desc->opptr;
int op = (opcode >> 39) & 3;
int trm = (opcode >> 38) & 1;
@@ -1752,13 +1741,13 @@ void mb86235_device::generate_xfer2(drcuml_block &block, compiler_state &compile
void mb86235_device::generate_double_xfer2(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc)
{
UML_MOV(block, mem(&m_core->pc), desc->pc);
- UML_DMOV(block, mem(&m_core->arg64), desc->opptr.q[0]);
+ UML_DMOV(block, mem(&m_core->arg64), desc->opptr);
UML_CALLC(block, cfunc_unimplemented_double_xfer2, this);
}
void mb86235_device::generate_xfer3(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc)
{
- uint64_t opcode = desc->opptr.q[0];
+ uint64_t opcode = desc->opptr;
uint32_t imm = (uint32_t)(opcode >> 27);
int dr = (opcode >> 19) & 0x7f;
@@ -1790,7 +1779,7 @@ void mb86235_device::generate_xfer3(drcuml_block &block, compiler_state &compile
void mb86235_device::generate_pre_control(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc)
{
- uint64_t op = desc->opptr.q[0];
+ uint64_t op = desc->opptr;
int ef1 = (op >> 16) & 0x3f;
int ef2 = op & 0xffff;
int cop = (op >> 22) & 0x1f;
diff --git a/src/devices/cpu/mb86235/mb86235fe.cpp b/src/devices/cpu/mb86235/mb86235fe.cpp
index 15151041d78..b82d1dca058 100644
--- a/src/devices/cpu/mb86235/mb86235fe.cpp
+++ b/src/devices/cpu/mb86235/mb86235fe.cpp
@@ -10,71 +10,41 @@
#include "emu.h"
#include "mb86235fe.h"
-#include "mb86235defs.h"
-
-
-#define AA_USED(desc,x) do { (desc).regin[0] |= 1 << (x); } while(0)
-#define AA_MODIFIED(desc,x) do { (desc).regout[0] |= 1 << (x); } while(0)
-#define AB_USED(desc,x) do { (desc).regin[0] |= 1 << (8+(x)); } while(0)
-#define AB_MODIFIED(desc,x) do { (desc).regout[0] |= 1 << (8+(x)); } while(0)
-#define MA_USED(desc,x) do { (desc).regin[0] |= 1 << (16+(x)); } while(0)
-#define MA_MODIFIED(desc,x) do { (desc).regout[0] |= 1 << (16+(x)); } while(0)
-#define MB_USED(desc,x) do { (desc).regin[0] |= 1 << (24+(x)); } while(0)
-#define MB_MODIFIED(desc,x) do { (desc).regout[0] |= 1 << (24+(x)); } while(0)
-#define AR_USED(desc,x) do { (desc).regin[1] |= 1 << (24+(x)); } while(0)
-#define AR_MODIFIED(desc,x) do { (desc).regout[1] |= 1 << (24+(x)); } while(0)
-
-#define AZ_USED(desc) do { (desc).regin[1] |= 1 << 0; } while (0)
-#define AZ_MODIFIED(desc) do { (desc).regout[1] |= 1 << 0; } while (0)
-#define AN_USED(desc) do { (desc).regin[1] |= 1 << 1; } while (0)
-#define AN_MODIFIED(desc) do { (desc).regout[1] |= 1 << 1; } while (0)
-#define AV_USED(desc) do { (desc).regin[1] |= 1 << 2; } while (0)
-#define AV_MODIFIED(desc) do { (desc).regout[1] |= 1 << 2; } while (0)
-#define AU_USED(desc) do { (desc).regin[1] |= 1 << 3; } while (0)
-#define AU_MODIFIED(desc) do { (desc).regout[1] |= 1 << 3; } while (0)
-#define AD_USED(desc) do { (desc).regin[1] |= 1 << 4; } while (0)
-#define AD_MODIFIED(desc) do { (desc).regout[1] |= 1 << 4; } while (0)
-#define ZC_USED(desc) do { (desc).regin[1] |= 1 << 5; } while (0)
-#define ZC_MODIFIED(desc) do { (desc).regout[1] |= 1 << 5; } while (0)
-#define IL_USED(desc) do { (desc).regin[1] |= 1 << 6; } while (0)
-#define IL_MODIFIED(desc) do { (desc).regout[1] |= 1 << 6; } while (0)
-#define NR_USED(desc) do { (desc).regin[1] |= 1 << 7; } while (0)
-#define NR_MODIFIED(desc) do { (desc).regout[1] |= 1 << 7; } while (0)
-#define ZD_USED(desc) do { (desc).regin[1] |= 1 << 8; } while (0)
-#define ZD_MODIFIED(desc) do { (desc).regout[1] |= 1 << 8; } while (0)
-#define MN_USED(desc) do { (desc).regin[1] |= 1 << 9; } while (0)
-#define MN_MODIFIED(desc) do { (desc).regout[1] |= 1 << 9; } while (0)
-#define MZ_USED(desc) do { (desc).regin[1] |= 1 << 10; } while (0)
-#define MZ_MODIFIED(desc) do { (desc).regout[1] |= 1 << 10; } while (0)
-#define MV_USED(desc) do { (desc).regin[1] |= 1 << 11; } while (0)
-#define MV_MODIFIED(desc) do { (desc).regout[1] |= 1 << 11; } while (0)
-#define MU_USED(desc) do { (desc).regin[1] |= 1 << 12; } while (0)
-#define MU_MODIFIED(desc) do { (desc).regout[1] |= 1 << 12; } while (0)
-#define MD_USED(desc) do { (desc).regin[1] |= 1 << 13; } while (0)
-#define MD_MODIFIED(desc) do { (desc).regout[1] |= 1 << 13; } while (0)
-
-
-mb86235_frontend::mb86235_frontend(mb86235_device *core, uint32_t window_start, uint32_t window_end, uint32_t max_sequence)
- : drc_frontend(*core, window_start, window_end, max_sequence),
+#include "cpu/drcfe.ipp"
+
+
+mb86235_device::frontend::frontend(mb86235_device *core, uint32_t window_start, uint32_t window_end, uint32_t max_sequence) :
+ drc_frontend_base(core->space_config(AS_PROGRAM)->page_shift(), window_start, window_end, max_sequence),
m_core(core)
{
}
+mb86235_device::frontend::~frontend()
+{
+}
+
+
+mb86235_device::opcode_desc const *mb86235_device::frontend::describe_code(offs_t startpc)
+{
+ return do_describe_code(
+ [this] (opcode_desc &desc, opcode_desc const *prev) { return describe(desc, prev); },
+ startpc);
+}
+
-bool mb86235_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
+bool mb86235_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev)
{
- uint64_t opcode = desc.opptr.q[0] = m_core->m_pcache.read_qword(desc.pc, 0);
+ uint64_t opcode = desc.opptr = m_core->m_pcache.read_qword(desc.pc, 0);
desc.length = 1;
- desc.cycles = 1;
// repeatable instruction needs an entry point
if (prev != nullptr)
{
- if (prev->userflags & OP_USERFLAG_REPEAT)
+ if (prev->repeat())
{
- desc.flags |= OPFLAG_IS_BRANCH_TARGET;
- desc.userflags |= OP_USERFLAG_REPEATED_OP;
+ desc.set_is_branch_target();
+ desc.set_repeated_op();
}
}
@@ -127,32 +97,29 @@ bool mb86235_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
return true;
}
-void mb86235_frontend::describe_alu_input(opcode_desc &desc, int reg)
+void mb86235_device::frontend::describe_alu_input(opcode_desc &desc, int reg)
{
switch (reg)
{
case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
- AA_USED(desc, reg & 7);
+ desc.set_aa_used(reg & 7);
break;
case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
- AB_USED(desc, reg & 7);
+ desc.set_ab_used(reg & 7);
break;
case 0x10: // PR
break;
case 0x11: // PR++
- desc.userflags &= ~OP_USERFLAG_PR_MASK;
- desc.userflags |= OP_USERFLAG_PR_INC;
+ desc.set_pr_inc();
break;
case 0x12: // PR--
- desc.userflags &= ~OP_USERFLAG_PR_MASK;
- desc.userflags |= OP_USERFLAG_PR_DEC;
+ desc.set_pr_dec();
break;
case 0x13: // PR#0
- desc.userflags &= ~OP_USERFLAG_PR_MASK;
- desc.userflags |= OP_USERFLAG_PR_ZERO;
+ desc.set_pr_zero();
break;
@@ -161,37 +128,37 @@ void mb86235_frontend::describe_alu_input(opcode_desc &desc, int reg)
}
}
-void mb86235_frontend::describe_mul_input(opcode_desc &desc, int reg)
+void mb86235_device::frontend::describe_mul_input(opcode_desc &desc, int reg)
{
switch (reg)
{
case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
- MA_USED(desc, reg & 7);
+ desc.set_ma_used(reg & 7);
break;
case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
- MB_USED(desc, reg & 7);
+ desc.set_mb_used(reg & 7);
break;
case 0x10: // PR
break;
case 0x11: // PR++
- if ((desc.userflags & OP_USERFLAG_PR_MASK) == 0) // ALU PR update has higher priority
+ if (desc.pr() == 0) // ALU PR update has higher priority
{
- desc.userflags |= OP_USERFLAG_PR_INC;
+ desc.set_pr_inc();
}
break;
case 0x12: // PR--
- if ((desc.userflags & OP_USERFLAG_PR_MASK) == 0) // ALU PR update has higher priority
+ if (desc.pr() == 0) // ALU PR update has higher priority
{
- desc.userflags |= OP_USERFLAG_PR_DEC;
+ desc.set_pr_dec();
}
break;
case 0x13: // PR#0
- if ((desc.userflags & OP_USERFLAG_PR_MASK) == 0) // ALU PR update has higher priority
+ if (desc.pr() == 0) // ALU PR update has higher priority
{
- desc.userflags |= OP_USERFLAG_PR_ZERO;
+ desc.set_pr_zero();
}
break;
@@ -200,24 +167,24 @@ void mb86235_frontend::describe_mul_input(opcode_desc &desc, int reg)
}
}
-void mb86235_frontend::describe_alumul_output(opcode_desc &desc, int reg)
+void mb86235_device::frontend::describe_alumul_output(opcode_desc &desc, int reg)
{
switch (reg >> 3)
{
case 0:
- MA_MODIFIED(desc, reg & 7);
+ desc.set_ma_modified(reg & 7);
break;
case 1:
- MB_MODIFIED(desc, reg & 7);
+ desc.set_mb_modified(reg & 7);
break;
case 2:
- AA_MODIFIED(desc, reg & 7);
+ desc.set_aa_modified(reg & 7);
break;
case 3:
- AB_MODIFIED(desc, reg & 7);
+ desc.set_ab_modified(reg & 7);
break;
default:
@@ -225,34 +192,34 @@ void mb86235_frontend::describe_alumul_output(opcode_desc &desc, int reg)
}
}
-void mb86235_frontend::describe_reg_read(opcode_desc &desc, int reg)
+void mb86235_device::frontend::describe_reg_read(opcode_desc &desc, int reg)
{
switch (reg)
{
case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
// MA0-7
- MA_USED(desc, reg & 7);
+ desc.set_ma_used(reg & 7);
break;
case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
// AA0-7
- AA_USED(desc, reg & 7);
+ desc.set_aa_used(reg & 7);
break;
case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
// AR0-7
- AR_USED(desc, reg & 7);
+ desc.set_ar_used(reg & 7);
break;
case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
// MB0-7
- MB_USED(desc, reg & 7);
+ desc.set_mb_used(reg & 7);
break;
case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
// AB0-7
- AB_USED(desc, reg & 7);
+ desc.set_ab_used(reg & 7);
break;
case 0x31: // FI
- desc.userflags |= OP_USERFLAG_FIFOIN;
- desc.flags |= OPFLAG_IS_BRANCH_TARGET; // fifo check makes this a branch target
+ desc.set_fifoin();
+ desc.set_is_branch_target(); // fifo check makes this a branch target
break;
case 0x32: // FO0
@@ -273,37 +240,37 @@ void mb86235_frontend::describe_reg_read(opcode_desc &desc, int reg)
break;
case 0x30: // PR
- if ((desc.userflags & OP_USERFLAG_PR_MASK) == 0) // ALU and MUL PR updates have higher priority
+ if (desc.pr() == 0) // ALU and MUL PR updates have higher priority
{
- desc.userflags |= OP_USERFLAG_PR_INC;
+ desc.set_pr_inc();
}
break;
}
}
-void mb86235_frontend::describe_reg_write(opcode_desc &desc, int reg)
+void mb86235_device::frontend::describe_reg_write(opcode_desc &desc, int reg)
{
switch (reg)
{
case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
// MA0-7
- MA_MODIFIED(desc, reg & 7);
+ desc.set_ma_modified(reg & 7);
break;
case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
// AA0-7
- AA_MODIFIED(desc, reg & 7);
+ desc.set_aa_modified(reg & 7);
break;
case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
// AR0-7
- AR_MODIFIED(desc, reg & 7);
+ desc.set_ar_modified(reg & 7);
break;
case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
// MB0-7
- MB_MODIFIED(desc, reg & 7);
+ desc.set_mb_modified(reg & 7);
break;
case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
// AB0-7
- AB_MODIFIED(desc, reg & 7);
+ desc.set_ab_modified(reg & 7);
break;
case 0x31: // FI
@@ -311,8 +278,8 @@ void mb86235_frontend::describe_reg_write(opcode_desc &desc, int reg)
case 0x32: // FO0
case 0x33: // FO1
- desc.userflags |= OP_USERFLAG_FIFOOUT;
- desc.flags |= OPFLAG_IS_BRANCH_TARGET; // fifo check makes this a branch target
+ desc.set_fifoout();
+ desc.set_is_branch_target(); // fifo check makes this a branch target
break;
case 0x10: // EB
@@ -329,14 +296,13 @@ void mb86235_frontend::describe_reg_write(opcode_desc &desc, int reg)
break;
case 0x30: // PR
- desc.userflags &= ~OP_USERFLAG_PW_MASK;
- desc.userflags |= OP_USERFLAG_PW_INC;
+ desc.set_pw_inc();
break;
}
}
-void mb86235_frontend::describe_alu(opcode_desc &desc, uint32_t aluop)
+void mb86235_device::frontend::describe_alu(opcode_desc &desc, uint32_t aluop)
{
int i1 = (aluop >> 10) & 0xf;
int i2 = (aluop >> 5) & 0x1f;
@@ -347,218 +313,218 @@ void mb86235_frontend::describe_alu(opcode_desc &desc, uint32_t aluop)
{
case 0x00: // FADD
describe_alu_input(desc, i1); describe_alu_input(desc, i2); describe_alumul_output(desc, io);
- AN_MODIFIED(desc);
- AZ_MODIFIED(desc);
- AV_MODIFIED(desc);
- AU_MODIFIED(desc);
+ desc.set_an_modified();
+ desc.set_az_modified();
+ desc.set_av_modified();
+ desc.set_au_modified();
break;
case 0x01: // FADDZ
describe_alu_input(desc, i1); describe_alu_input(desc, i2); describe_alumul_output(desc, io);
- ZC_MODIFIED(desc);
- AN_MODIFIED(desc);
- AZ_MODIFIED(desc);
- AV_MODIFIED(desc);
- AU_MODIFIED(desc);
- AD_MODIFIED(desc);
+ desc.set_zc_modified();
+ desc.set_an_modified();
+ desc.set_az_modified();
+ desc.set_av_modified();
+ desc.set_au_modified();
+ desc.set_ad_modified();
break;
case 0x02: // FSUB
describe_alu_input(desc, i1); describe_alu_input(desc, i2); describe_alumul_output(desc, io);
- AN_MODIFIED(desc);
- AZ_MODIFIED(desc);
- AV_MODIFIED(desc);
- AU_MODIFIED(desc);
- AD_MODIFIED(desc);
+ desc.set_an_modified();
+ desc.set_az_modified();
+ desc.set_av_modified();
+ desc.set_au_modified();
+ desc.set_ad_modified();
break;
case 0x03: // FSUBZ
describe_alu_input(desc, i1); describe_alu_input(desc, i2); describe_alumul_output(desc, io);
- ZC_MODIFIED(desc);
- AN_MODIFIED(desc);
- AZ_MODIFIED(desc);
- AV_MODIFIED(desc);
- AU_MODIFIED(desc);
- AD_MODIFIED(desc);
+ desc.set_zc_modified();
+ desc.set_an_modified();
+ desc.set_az_modified();
+ desc.set_av_modified();
+ desc.set_au_modified();
+ desc.set_ad_modified();
break;
case 0x04: // FCMP
describe_alu_input(desc, i1); describe_alu_input(desc, i2);
- AN_MODIFIED(desc);
- AZ_MODIFIED(desc);
- AV_MODIFIED(desc);
- AU_MODIFIED(desc);
- AD_MODIFIED(desc);
+ desc.set_an_modified();
+ desc.set_az_modified();
+ desc.set_av_modified();
+ desc.set_au_modified();
+ desc.set_ad_modified();
break;
case 0x05: // FABS
describe_alu_input(desc, i1); describe_alumul_output(desc, io);
- AN_MODIFIED(desc);
- AZ_MODIFIED(desc);
- AD_MODIFIED(desc);
+ desc.set_an_modified();
+ desc.set_az_modified();
+ desc.set_ad_modified();
break;
case 0x06: // FABC
describe_alu_input(desc, i1); describe_alu_input(desc, i2); describe_alumul_output(desc, io);
- AN_MODIFIED(desc);
- AZ_MODIFIED(desc);
- AU_MODIFIED(desc);
- AD_MODIFIED(desc);
+ desc.set_an_modified();
+ desc.set_az_modified();
+ desc.set_au_modified();
+ desc.set_ad_modified();
break;
case 0x07: // NOP
break;
case 0x08: // FEA
describe_alu_input(desc, i1); describe_alumul_output(desc, io);
- AN_MODIFIED(desc);
- AZ_MODIFIED(desc);
- AV_MODIFIED(desc);
- AD_MODIFIED(desc);
+ desc.set_an_modified();
+ desc.set_az_modified();
+ desc.set_av_modified();
+ desc.set_ad_modified();
break;
case 0x09: // FES
describe_alu_input(desc, i1); describe_alumul_output(desc, io);
- AN_MODIFIED(desc);
- AZ_MODIFIED(desc);
- AU_MODIFIED(desc);
- AD_MODIFIED(desc);
+ desc.set_an_modified();
+ desc.set_az_modified();
+ desc.set_au_modified();
+ desc.set_ad_modified();
break;
case 0x0a: // FRCP
describe_alu_input(desc, i1); describe_alumul_output(desc, io);
- ZD_MODIFIED(desc);
- AN_MODIFIED(desc);
- AZ_MODIFIED(desc);
- AU_MODIFIED(desc);
- AD_MODIFIED(desc);
+ desc.set_zd_modified();
+ desc.set_an_modified();
+ desc.set_az_modified();
+ desc.set_au_modified();
+ desc.set_ad_modified();
break;
case 0x0b: // FRSQ
describe_alu_input(desc, i1); describe_alumul_output(desc, io);
- NR_MODIFIED(desc);
- AN_MODIFIED(desc);
- AZ_MODIFIED(desc);
- AU_MODIFIED(desc);
- AD_MODIFIED(desc);
+ desc.set_nr_modified();
+ desc.set_an_modified();
+ desc.set_az_modified();
+ desc.set_au_modified();
+ desc.set_ad_modified();
break;
case 0x0c: // FLOG
describe_alu_input(desc, i1); describe_alumul_output(desc, io);
- IL_MODIFIED(desc);
- AN_MODIFIED(desc);
- AZ_MODIFIED(desc);
- AD_MODIFIED(desc);
+ desc.set_il_modified();
+ desc.set_an_modified();
+ desc.set_az_modified();
+ desc.set_ad_modified();
break;
case 0x0d: // CIF
describe_alu_input(desc, i1); describe_alumul_output(desc, io);
- AN_MODIFIED(desc);
- AZ_MODIFIED(desc);
+ desc.set_an_modified();
+ desc.set_az_modified();
break;
case 0x0e: // CFI
describe_alu_input(desc, i1); describe_alumul_output(desc, io);
- AN_MODIFIED(desc);
- AZ_MODIFIED(desc);
- AV_MODIFIED(desc);
- AD_MODIFIED(desc);
+ desc.set_an_modified();
+ desc.set_az_modified();
+ desc.set_av_modified();
+ desc.set_ad_modified();
break;
case 0x0f: // CFIB
describe_alu_input(desc, i1); describe_alumul_output(desc, io);
- AN_MODIFIED(desc);
- AZ_MODIFIED(desc);
- AV_MODIFIED(desc);
- AD_MODIFIED(desc);
- AU_MODIFIED(desc);
+ desc.set_an_modified();
+ desc.set_az_modified();
+ desc.set_av_modified();
+ desc.set_ad_modified();
+ desc.set_au_modified();
break;
case 0x10: // ADD
describe_alu_input(desc, i1); describe_alu_input(desc, i2); describe_alumul_output(desc, io);
- AN_MODIFIED(desc);
- AZ_MODIFIED(desc);
- AV_MODIFIED(desc);
+ desc.set_an_modified();
+ desc.set_az_modified();
+ desc.set_av_modified();
break;
case 0x11: // ADDZ
describe_alu_input(desc, i1); describe_alu_input(desc, i2); describe_alumul_output(desc, io);
- ZC_MODIFIED(desc);
- AN_MODIFIED(desc);
- AZ_MODIFIED(desc);
- AV_MODIFIED(desc);
+ desc.set_zc_modified();
+ desc.set_an_modified();
+ desc.set_az_modified();
+ desc.set_av_modified();
break;
case 0x12: // SUB
describe_alu_input(desc, i1); describe_alu_input(desc, i2); describe_alumul_output(desc, io);
- AN_MODIFIED(desc);
- AZ_MODIFIED(desc);
- AV_MODIFIED(desc);
+ desc.set_an_modified();
+ desc.set_az_modified();
+ desc.set_av_modified();
break;
case 0x13: // SUBZ
describe_alu_input(desc, i1); describe_alu_input(desc, i2); describe_alumul_output(desc, io);
- ZC_MODIFIED(desc);
- AN_MODIFIED(desc);
- AZ_MODIFIED(desc);
- AV_MODIFIED(desc);
+ desc.set_zc_modified();
+ desc.set_an_modified();
+ desc.set_az_modified();
+ desc.set_av_modified();
break;
case 0x14: // CMP
describe_alu_input(desc, i1); describe_alu_input(desc, i2);
- AN_MODIFIED(desc);
- AZ_MODIFIED(desc);
- AV_MODIFIED(desc);
+ desc.set_an_modified();
+ desc.set_az_modified();
+ desc.set_av_modified();
break;
case 0x15: // ABS
describe_alu_input(desc, i1); describe_alumul_output(desc, io);
- AN_MODIFIED(desc);
- AZ_MODIFIED(desc);
- AV_MODIFIED(desc);
+ desc.set_an_modified();
+ desc.set_az_modified();
+ desc.set_av_modified();
break;
case 0x16: // ATR
describe_alu_input(desc, i1); describe_alumul_output(desc, io);
break;
case 0x17: // ATRZ
describe_alu_input(desc, i1); describe_alumul_output(desc, io);
- ZC_MODIFIED(desc);
+ desc.set_zc_modified();
break;
case 0x18: // AND
describe_alu_input(desc, i1); describe_alu_input(desc, i2); describe_alumul_output(desc, io);
- AN_MODIFIED(desc);
- AZ_MODIFIED(desc);
- AV_MODIFIED(desc);
- AU_MODIFIED(desc);
+ desc.set_an_modified();
+ desc.set_az_modified();
+ desc.set_av_modified();
+ desc.set_au_modified();
break;
case 0x19: // OR
describe_alu_input(desc, i1); describe_alu_input(desc, i2); describe_alumul_output(desc, io);
- AN_MODIFIED(desc);
- AZ_MODIFIED(desc);
- AV_MODIFIED(desc);
- AU_MODIFIED(desc);
+ desc.set_an_modified();
+ desc.set_az_modified();
+ desc.set_av_modified();
+ desc.set_au_modified();
break;
case 0x1a: // XOR
describe_alu_input(desc, i1); describe_alu_input(desc, i2); describe_alumul_output(desc, io);
- AN_MODIFIED(desc);
- AZ_MODIFIED(desc);
- AV_MODIFIED(desc);
- AU_MODIFIED(desc);
+ desc.set_an_modified();
+ desc.set_az_modified();
+ desc.set_av_modified();
+ desc.set_au_modified();
break;
case 0x1b: // NOT
describe_alu_input(desc, i1); describe_alumul_output(desc, io);
- AN_MODIFIED(desc);
- AZ_MODIFIED(desc);
- AV_MODIFIED(desc);
- AU_MODIFIED(desc);
+ desc.set_an_modified();
+ desc.set_az_modified();
+ desc.set_av_modified();
+ desc.set_au_modified();
break;
case 0x1c: // LSR
describe_alu_input(desc, i1); describe_alumul_output(desc, io);
- AN_MODIFIED(desc);
- AZ_MODIFIED(desc);
- AV_MODIFIED(desc);
- AU_MODIFIED(desc);
+ desc.set_an_modified();
+ desc.set_az_modified();
+ desc.set_av_modified();
+ desc.set_au_modified();
break;
case 0x1d: // LSL
describe_alu_input(desc, i1); describe_alumul_output(desc, io);
- AN_MODIFIED(desc);
- AZ_MODIFIED(desc);
- AV_MODIFIED(desc);
- AU_MODIFIED(desc);
+ desc.set_an_modified();
+ desc.set_az_modified();
+ desc.set_av_modified();
+ desc.set_au_modified();
break;
case 0x1e: // ASR
describe_alu_input(desc, i1); describe_alumul_output(desc, io);
- AN_MODIFIED(desc);
- AZ_MODIFIED(desc);
+ desc.set_an_modified();
+ desc.set_az_modified();
break;
case 0x1f: // ASL
describe_alu_input(desc, i1); describe_alumul_output(desc, io);
- AN_MODIFIED(desc);
- AZ_MODIFIED(desc);
+ desc.set_an_modified();
+ desc.set_az_modified();
break;
}
}
-void mb86235_frontend::describe_mul(opcode_desc &desc, uint32_t mulop)
+void mb86235_device::frontend::describe_mul(opcode_desc &desc, uint32_t mulop)
{
int i1 = (mulop >> 10) & 0xf;
int i2 = (mulop >> 5) & 0x1f;
@@ -572,78 +538,78 @@ void mb86235_frontend::describe_mul(opcode_desc &desc, uint32_t mulop)
if (m)
{
// FMUL
- MN_MODIFIED(desc);
- MZ_MODIFIED(desc);
- MV_MODIFIED(desc);
- MU_MODIFIED(desc);
- MD_MODIFIED(desc);
+ desc.set_mn_modified();
+ desc.set_mz_modified();
+ desc.set_mv_modified();
+ desc.set_mu_modified();
+ desc.set_md_modified();
}
else
{
// MUL
- MN_MODIFIED(desc);
- MZ_MODIFIED(desc);
- MV_MODIFIED(desc);
+ desc.set_mn_modified();
+ desc.set_mz_modified();
+ desc.set_mv_modified();
}
}
-void mb86235_frontend::describe_ea(opcode_desc &desc, int md, int arx, int ary, int disp)
+void mb86235_device::frontend::describe_ea(opcode_desc &desc, int md, int arx, int ary, int disp)
{
switch (md)
{
case 0x0: // @ARx
- AR_USED(desc, arx);
+ desc.set_ar_used(arx);
break;
case 0x1: // @ARx++
- AR_USED(desc, arx); AR_MODIFIED(desc, arx);
+ desc.set_ar_used(arx); desc.set_ar_modified(arx);
break;
case 0x2: // @ARx--
- AR_USED(desc, arx); AR_MODIFIED(desc, arx);
+ desc.set_ar_used(arx); desc.set_ar_modified(arx);
break;
case 0x3: // @ARx++disp
- AR_USED(desc, arx); AR_MODIFIED(desc, arx);
+ desc.set_ar_used(arx); desc.set_ar_modified(arx);
break;
case 0x4: // @ARx+ARy
- AR_USED(desc, arx); AR_USED(desc, ary);
+ desc.set_ar_used(arx); desc.set_ar_used(ary);
break;
case 0x5: // @ARx+ARy++
- AR_USED(desc, arx); AR_USED(desc, ary); AR_MODIFIED(desc, ary);
+ desc.set_ar_used(arx); desc.set_ar_used(ary); desc.set_ar_modified(ary);
break;
case 0x6: // @ARx+ARy--
- AR_USED(desc, arx); AR_USED(desc, ary); AR_MODIFIED(desc, ary);
+ desc.set_ar_used(arx); desc.set_ar_used(ary); desc.set_ar_modified(ary);
break;
case 0x7: // @ARx+ARy++disp
- AR_USED(desc, arx); AR_USED(desc, ary); AR_MODIFIED(desc, ary);
+ desc.set_ar_used(arx); desc.set_ar_used(ary); desc.set_ar_modified(ary);
break;
case 0x8: // @ARx+ARyU
- AR_USED(desc, arx); AR_USED(desc, ary);
+ desc.set_ar_used(arx); desc.set_ar_used(ary);
break;
case 0x9: // @ARx+ARyL
- AR_USED(desc, arx); AR_USED(desc, ary);
+ desc.set_ar_used(arx); desc.set_ar_used(ary);
break;
case 0xa: // @ARx+disp
- AR_USED(desc, arx);
+ desc.set_ar_used(arx);
break;
case 0xb: // @ARx+ARy+disp
- AR_USED(desc, arx); AR_USED(desc, ary);
+ desc.set_ar_used(arx); desc.set_ar_used(ary);
break;
case 0xc: // @disp
break;
case 0xd: // @ARx+[ARy++]
- AR_USED(desc, arx); AR_USED(desc, ary); AR_MODIFIED(desc, ary);
+ desc.set_ar_used(arx); desc.set_ar_used(ary); desc.set_ar_modified(ary);
break;
case 0xe: // @ARx+[ARy--]
- AR_USED(desc, arx); AR_USED(desc, ary); AR_MODIFIED(desc, ary);
+ desc.set_ar_used(arx); desc.set_ar_used(ary); desc.set_ar_modified(ary);
break;
case 0xf: // @ARx+[ARy++disp]
- AR_USED(desc, arx); AR_USED(desc, ary); AR_MODIFIED(desc, ary);
+ desc.set_ar_used(arx); desc.set_ar_used(ary); desc.set_ar_modified(ary);
break;
}
}
-void mb86235_frontend::describe_xfer1(opcode_desc &desc)
+void mb86235_device::frontend::describe_xfer1(opcode_desc &desc)
{
- uint64_t opcode = desc.opptr.q[0];
+ uint64_t opcode = desc.opptr;
int dr = (opcode >> 12) & 0x7f;
int sr = (opcode >> 19) & 0x7f;
@@ -666,7 +632,7 @@ void mb86235_frontend::describe_xfer1(opcode_desc &desc)
else
{
describe_ea(desc, md, sr & 7, ary, disp5);
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_reads_memory();
}
if ((dr & 0x40) == 0)
@@ -676,7 +642,7 @@ void mb86235_frontend::describe_xfer1(opcode_desc &desc)
else
{
describe_ea(desc, md, dr & 7, ary, disp5);
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_writes_memory();
}
}
else
@@ -685,26 +651,26 @@ void mb86235_frontend::describe_xfer1(opcode_desc &desc)
if (dir == 0)
{
describe_reg_read(desc, dr & 0x3f);
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_writes_memory();
}
else
{
describe_reg_write(desc, dr & 0x3f);
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_reads_memory();
}
}
}
-void mb86235_frontend::describe_double_xfer1(opcode_desc &desc)
+void mb86235_device::frontend::describe_double_xfer1(opcode_desc &desc)
{
- uint64_t opcode = desc.opptr.q[0];
+ uint64_t opcode = desc.opptr;
- fatalerror("mb86235_frontend: describe_double_xfer1 at %08X (%08X%08X)", desc.pc, (uint32_t)(opcode >> 32), (uint32_t)(opcode));
+ fatalerror("mb86235_device::frontend: describe_double_xfer1 at %08X (%08X%08X)", desc.pc, (uint32_t)(opcode >> 32), (uint32_t)(opcode));
}
-void mb86235_frontend::describe_xfer2(opcode_desc &desc)
+void mb86235_device::frontend::describe_xfer2(opcode_desc &desc)
{
- uint64_t opcode = desc.opptr.q[0];
+ uint64_t opcode = desc.opptr;
int op = (opcode >> 39) & 3;
int trm = (opcode >> 38) & 1;
@@ -730,7 +696,7 @@ void mb86235_frontend::describe_xfer2(opcode_desc &desc)
else
{
describe_ea(desc, md, sr & 7, ary, disp14);
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_reads_memory();
}
if ((dr & 0x40) == 0)
@@ -740,7 +706,7 @@ void mb86235_frontend::describe_xfer2(opcode_desc &desc)
else
{
describe_ea(desc, md, dr & 7, ary, disp14);
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_writes_memory();
}
}
else
@@ -749,31 +715,31 @@ void mb86235_frontend::describe_xfer2(opcode_desc &desc)
if (dir == 0)
{
describe_reg_read(desc, dr & 0x3f);
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_writes_memory();
}
else
{
describe_reg_write(desc, dr & 0x3f);
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_reads_memory();
}
}
}
else if (op == 2) // MOV4
{
- fatalerror("mb86235_frontend: describe_xfer2 MOV4 at %08X (%08X%08X)", desc.pc, (uint32_t)(opcode >> 32), (uint32_t)(opcode));
+ fatalerror("mb86235_device::frontend: describe_xfer2 MOV4 at %08X (%08X%08X)", desc.pc, (uint32_t)(opcode >> 32), (uint32_t)(opcode));
}
}
-void mb86235_frontend::describe_double_xfer2(opcode_desc &desc)
+void mb86235_device::frontend::describe_double_xfer2(opcode_desc &desc)
{
- uint64_t opcode = desc.opptr.q[0];
- fatalerror("mb86235_frontend: describe_double_xfer2 at %08X (%08X%08X)", desc.pc, (uint32_t)(opcode >> 32), (uint32_t)(opcode));
+ uint64_t opcode = desc.opptr;
+ fatalerror("mb86235_device::frontend: describe_double_xfer2 at %08X (%08X%08X)", desc.pc, (uint32_t)(opcode >> 32), (uint32_t)(opcode));
}
-void mb86235_frontend::describe_xfer3(opcode_desc &desc)
+void mb86235_device::frontend::describe_xfer3(opcode_desc &desc)
{
- uint64_t opcode = desc.opptr.q[0];
+ uint64_t opcode = desc.opptr;
int dr = (opcode >> 19) & 0x7f;
int disp = (opcode >> 7) & 0xfff;
@@ -789,18 +755,18 @@ void mb86235_frontend::describe_xfer3(opcode_desc &desc)
case 2: // RAM-A
case 3: // RAM-B
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_writes_memory();
describe_ea(desc, md, dr & 7, ary, disp);
break;
}
}
-void mb86235_frontend::describe_control(opcode_desc &desc)
+void mb86235_device::frontend::describe_control(opcode_desc &desc)
{
- int ef1 = (desc.opptr.q[0] >> 16) & 0x3f;
- int ef2 = desc.opptr.q[0] & 0xffff;
- int cop = (desc.opptr.q[0] >> 22) & 0x1f;
- int rel12 = util::sext<int>(desc.opptr.q[0], 12);
+ int ef1 = (desc.opptr >> 16) & 0x3f;
+ int ef2 = desc.opptr & 0xffff;
+ int cop = (desc.opptr >> 22) & 0x1f;
+ int rel12 = util::sext<unsigned>(desc.opptr, 12);
switch (cop)
{
@@ -808,13 +774,13 @@ void mb86235_frontend::describe_control(opcode_desc &desc)
break;
case 0x01: // REP
if (ef1 != 0) // ARx
- AR_USED(desc, (ef2 >> 12) & 7);
+ desc.set_ar_used((ef2 >> 12) & 7);
- desc.userflags |= OP_USERFLAG_REPEAT;
+ desc.set_repeat();
break;
case 0x02: // SETL
if (ef1 != 0) // ARx
- AR_USED(desc, (ef2 >> 12) & 7);
+ desc.set_ar_used((ef2 >> 12) & 7);
break;
case 0x03: // CLRFI/CLRFO/CLRF
break;
@@ -837,24 +803,25 @@ void mb86235_frontend::describe_control(opcode_desc &desc)
case 0x0d: // SETM #imm1, WAIT
break;
case 0x13: // DBLP rel12
- desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+ desc.set_is_conditional_branch();
desc.targetpc = desc.pc + rel12;
desc.delayslots = 1;
break;
case 0x14: // DBBC ARx:y, rel12
- desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+ desc.set_is_conditional_branch();
desc.targetpc = desc.pc + rel12;
desc.delayslots = 1;
- AR_USED(desc, ((desc.opptr.q[0] >> 13) & 7));
+ desc.set_ar_used(((desc.opptr >> 13) & 7));
break;
case 0x15: // DBBS ARx:y, rel12
- desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+ desc.set_is_conditional_branch();
desc.targetpc = desc.pc + rel12;
desc.delayslots = 1;
- AR_USED(desc, ((desc.opptr.q[0] >> 13) & 7));
+ desc.set_ar_used(((desc.opptr >> 13) & 7));
break;
case 0x1b: // DRET
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
desc.targetpc = BRANCH_TARGET_DYNAMIC;
desc.delayslots = 1;
break;
@@ -864,7 +831,7 @@ void mb86235_frontend::describe_control(opcode_desc &desc)
case 0x18: // DCcc
case 0x19: // DCNcc
{
- switch ((desc.opptr.q[0] >> 12) & 0xf)
+ switch ((desc.opptr >> 12) & 0xf)
{
case 0x0: desc.targetpc = ef2 & 0xfff; break;
case 0x1: desc.targetpc = desc.pc + rel12; break;
@@ -884,7 +851,7 @@ void mb86235_frontend::describe_control(opcode_desc &desc)
case 0xf: desc.targetpc = BRANCH_TARGET_DYNAMIC; describe_reg_read(desc, (ef2 >> 6) & 0x3f); break;
}
- desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+ desc.set_is_conditional_branch();
desc.delayslots = 1;
break;
}
@@ -892,7 +859,7 @@ void mb86235_frontend::describe_control(opcode_desc &desc)
case 0x1a: // DCALL
case 0x12: // DJMP
{
- switch ((desc.opptr.q[0] >> 12) & 0xf)
+ switch ((desc.opptr >> 12) & 0xf)
{
case 0x0: desc.targetpc = ef2 & 0xfff; break;
case 0x1: desc.targetpc = desc.pc + rel12; break;
@@ -912,7 +879,8 @@ void mb86235_frontend::describe_control(opcode_desc &desc)
case 0xf: desc.targetpc = BRANCH_TARGET_DYNAMIC; describe_reg_read(desc, (ef2 >> 6) & 0x3f); break;
}
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
desc.delayslots = 1;
break;
}
diff --git a/src/devices/cpu/mb86235/mb86235fe.h b/src/devices/cpu/mb86235/mb86235fe.h
index ed160a98c0a..0cf63cb0982 100644
--- a/src/devices/cpu/mb86235/mb86235fe.h
+++ b/src/devices/cpu/mb86235/mb86235fe.h
@@ -13,20 +13,175 @@
#pragma once
#include "mb86235.h"
+
#include "cpu/drcfe.h"
-class mb86235_frontend : public drc_frontend
+#include <cassert>
+
+
+class mb86235_device::opcode_desc : public opcode_desc_base<opcode_desc, 56>
+{
+public:
+ enum : uint8_t { INC = 1, DEC, ZERO };
+
+ uint64_t opptr; // copy of opcode
+
+ void set_aa_used(unsigned n) { regin.set(REG_AA0 + n); }
+ void set_aa_modified(unsigned n) { regout.set(REG_AA0 + n); }
+ void set_ab_used(unsigned n) { regin.set(REG_AB0 + n); }
+ void set_ab_modified(unsigned n) { regout.set(REG_AB0 + n); }
+ void set_ma_used(unsigned n) { regin.set(REG_MA0 + n); }
+ void set_ma_modified(unsigned n) { regout.set(REG_MA0 + n); }
+ void set_mb_used(unsigned n) { regin.set(REG_MB0 + n); }
+ void set_mb_modified(unsigned n) { regout.set(REG_MB0 + n); }
+ void set_ar_used(unsigned n) { regin.set(REG_AR0 + n); }
+ void set_ar_modified(unsigned n) { regout.set(REG_AR0 + n); }
+
+ void set_az_used() { regin.set(REG_AZ); }
+ void set_az_modified() { regout.set(REG_AZ); }
+ void set_an_used() { regin.set(REG_AN); }
+ void set_an_modified() { regout.set(REG_AN); }
+ void set_av_used() { regin.set(REG_AV); }
+ void set_av_modified() { regout.set(REG_AV); }
+ void set_au_used() { regin.set(REG_AU); }
+ void set_au_modified() { regout.set(REG_AU); }
+ void set_ad_used() { regin.set(REG_AD); }
+ void set_ad_modified() { regout.set(REG_AD); }
+ void set_zc_used() { regin.set(REG_ZC); }
+ void set_zc_modified() { regout.set(REG_ZC); }
+ void set_il_used() { regin.set(REG_IL); }
+ void set_il_modified() { regout.set(REG_IL); }
+ void set_nr_used() { regin.set(REG_NR); }
+ void set_nr_modified() { regout.set(REG_NR); }
+ void set_zd_used() { regin.set(REG_ZD); }
+ void set_zd_modified() { regout.set(REG_ZD); }
+ void set_mn_used() { regin.set(REG_MN); }
+ void set_mn_modified() { regout.set(REG_MN); }
+ void set_mz_used() { regin.set(REG_MZ); }
+ void set_mz_modified() { regout.set(REG_MZ); }
+ void set_mv_used() { regin.set(REG_MV); }
+ void set_mv_modified() { regout.set(REG_MV); }
+ void set_mu_used() { regin.set(REG_MU); }
+ void set_mu_modified() { regout.set(REG_MU); }
+ void set_md_used() { regin.set(REG_MD); }
+ void set_md_modified() { regout.set(REG_MD); }
+
+ bool aa_used(unsigned n) const { return regin[REG_AA0 + n]; }
+ bool aa_modified(unsigned n) const { return regout[REG_AA0 + n]; }
+ bool ab_used(unsigned n) const { return regin[REG_AB0 + n]; }
+ bool ab_modified(unsigned n) const { return regout[REG_AB0 + n]; }
+ bool ma_used(unsigned n) const { return regin[REG_MA0 + n]; }
+ bool ma_modified(unsigned n) const { return regout[REG_MA0 + n]; }
+ bool mb_used(unsigned n) const { return regin[REG_MB0 + n]; }
+ bool mb_modified(unsigned n) const { return regout[REG_MB0 + n]; }
+ bool ar_used(unsigned n) const { return regin[REG_AR0 + n]; }
+ bool ar_modified(unsigned n) const { return regout[REG_AR0 + n]; }
+
+ bool az_calc_required() const { return regreq[REG_AZ] || in_delay_slot(); }
+ bool an_calc_required() const { return regreq[REG_AN] || in_delay_slot(); }
+ bool av_calc_required() const { return regreq[REG_AV] || in_delay_slot(); }
+ bool au_calc_required() const { return regreq[REG_AU] || in_delay_slot(); }
+ bool ad_calc_required() const { return regreq[REG_AD] || in_delay_slot(); }
+ bool zc_calc_required() const { return regreq[REG_ZC] || in_delay_slot(); }
+ bool il_calc_required() const { return regreq[REG_IL] || in_delay_slot(); }
+ bool nr_calc_required() const { return regreq[REG_NR] || in_delay_slot(); }
+ bool zd_calc_required() const { return regreq[REG_ZD] || in_delay_slot(); }
+ bool mn_calc_required() const { return regreq[REG_MN] || in_delay_slot(); }
+ bool mz_calc_required() const { return regreq[REG_MZ] || in_delay_slot(); }
+ 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 md_calc_required() const { return regreq[REG_MD] || in_delay_slot(); }
+
+ void set_reads_memory() { m_reads_memory = true; }
+ void set_writes_memory() { m_writes_memory = true; }
+ void set_fifoin() { m_fifoin = true; }
+ void set_fifoout() { m_fifoout = true; }
+ void set_repeat() { m_repeat = true; }
+ void set_repeated_op() { m_repeated_op = true; }
+ void set_pr_inc() { m_pr = INC; }
+ void set_pr_dec() { m_pr = DEC; }
+ void set_pr_zero() { m_pr = ZERO; }
+ void set_pw_inc() { m_pw = INC; }
+ void set_pw_dec() { m_pw = DEC; }
+ void set_pw_zero() { m_pw = ZERO; }
+
+ bool reads_memory() const { return m_reads_memory; }
+ bool writes_memory() const { return m_writes_memory; }
+ bool fifoin() const { return m_fifoin; }
+ bool fifoout() const { return m_fifoout; }
+ bool repeat() const { return m_repeat; }
+ bool repeated_op() const { return m_repeated_op; }
+ uint8_t pr() const { return m_pr; }
+ uint8_t pw() const { return m_pw; }
+
+ void reset(offs_t curpc, bool in_delay_slot)
+ {
+ static_assert(REG_COUNT <= 56);
+
+ opcode_desc_base::reset(curpc, in_delay_slot);
+
+ opptr = 0;
+ m_reads_memory = false;
+ m_writes_memory = false;
+ m_fifoin = false;
+ m_fifoout = false;
+ m_repeat = false;
+ m_repeated_op = false;
+ m_pr = 0;
+ m_pw = 0;
+ }
+
+private:
+ enum
+ {
+ REG_AA0 = 0,
+ REG_AB0 = REG_AA0 + 8,
+ REG_MA0 = REG_AB0 + 8,
+ REG_MB0 = REG_MA0 + 8,
+ REG_AR0 = REG_MB0 + 8,
+
+ REG_AZ = REG_AR0 + 8,
+ REG_AN,
+ REG_AV,
+ REG_AU,
+ REG_AD,
+ REG_ZC,
+ REG_IL,
+ REG_NR,
+ REG_ZD,
+ REG_MN,
+ REG_MZ,
+ REG_MV,
+ REG_MU,
+ REG_MD,
+
+ REG_COUNT
+ };
+
+ bool m_reads_memory;
+ bool m_writes_memory;
+ bool m_fifoin;
+ bool m_fifoout;
+ bool m_repeat;
+ bool m_repeated_op;
+ uint8_t m_pr;
+ uint8_t m_pw;
+};
+
+
+class mb86235_device::frontend : public drc_frontend_base<opcode_desc>
{
public:
- mb86235_frontend(mb86235_device *core, uint32_t window_start, uint32_t window_end, uint32_t max_sequence);
+ frontend(mb86235_device *core, uint32_t window_start, uint32_t window_end, uint32_t max_sequence);
+ ~frontend();
-protected:
- // required overrides
- virtual bool describe(opcode_desc &desc, const opcode_desc *prev) override;
+ opcode_desc const *describe_code(offs_t startpc);
private:
mb86235_device *m_core;
+ bool describe(opcode_desc &desc, opcode_desc const *prev);
+
void describe_alu(opcode_desc &desc, uint32_t aluop);
void describe_mul(opcode_desc &desc, uint32_t mulop);
void describe_xfer1(opcode_desc &desc);
diff --git a/src/devices/cpu/mips/mips3.cpp b/src/devices/cpu/mips/mips3.cpp
index a56f19a3b21..110aef87928 100644
--- a/src/devices/cpu/mips/mips3.cpp
+++ b/src/devices/cpu/mips/mips3.cpp
@@ -13,6 +13,7 @@
#include "mips3com.h"
#include "mips3dsm.h"
+#include "mips3fe.h"
#include "ps2vu.h"
#include "emuopts.h"
@@ -219,6 +220,10 @@ mips3_device::mips3_device(const machine_config &mconfig, device_type type, cons
set_vtlb_fixed_entries(2 * m_tlbentries + 2);
}
+mips3_device::~mips3_device()
+{
+}
+
device_memory_interface::space_config_vector mips3_device::memory_space_config() const
{
return space_config_vector {
@@ -486,7 +491,7 @@ void mips3_device::device_start()
m_drcuml->symbol_add(&m_fpmode, sizeof(m_fpmode), "fpmode");
/* initialize the front-end helper */
- m_drcfe = std::make_unique<mips3_frontend>(this, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, SINGLE_INSTRUCTION_MODE ? 1 : COMPILE_MAX_SEQUENCE);
+ m_drcfe = std::make_unique<frontend>(this, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, SINGLE_INSTRUCTION_MODE ? 1 : COMPILE_MAX_SEQUENCE);
/* allocate memory for cache-local state and initialize it */
memcpy(m_fpmode, fpmode_source, sizeof(fpmode_source));
diff --git a/src/devices/cpu/mips/mips3.h b/src/devices/cpu/mips/mips3.h
index 181df0e9a47..bcf6891bd0b 100644
--- a/src/devices/cpu/mips/mips3.h
+++ b/src/devices/cpu/mips/mips3.h
@@ -14,13 +14,14 @@ MIPS III/IV emulator.
#pragma once
+#include "ps2vu.h"
-#include "cpu/drcfe.h"
#include "cpu/drcuml.h"
-#include "ps2vu.h"
#include "divtlb.h"
+#include <bitset>
+
DECLARE_DEVICE_TYPE(R4000BE, r4000be_device)
DECLARE_DEVICE_TYPE(R4000LE, r4000le_device)
@@ -257,11 +258,10 @@ INTERRUPT CONSTANTS
STRUCTURES
***************************************************************************/
-class mips3_frontend;
-
class mips3_device : public cpu_device, public device_vtlb_interface {
protected:
- friend class mips3_frontend;
+ class frontend;
+ class opcode_desc;
/* MIPS flavors */
enum mips3_flavor {
@@ -303,6 +303,7 @@ protected:
public:
// construction/destruction
mips3_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, mips3_flavor flavor, endianness_t endiannes, uint32_t data_bits);
+ virtual ~mips3_device();
void set_drc_cache_size(size_t bytes) { m_drc_cache.set_size(bytes); }
void set_icache_size(size_t icache_size) { c_icache_size = icache_size; }
@@ -480,8 +481,8 @@ protected:
/* core state */
drc_cache m_drc_cache; /* pointer to the DRC code cache */
- std::unique_ptr<drcuml_state> m_drcuml;/* DRC UML generator state */
- std::unique_ptr<mips3_frontend> m_drcfe; /* pointer to the DRC front-end state */
+ std::unique_ptr<drcuml_state> m_drcuml; /* DRC UML generator state */
+ std::unique_ptr<frontend> m_drcfe; /* pointer to the DRC front-end state */
uint32_t m_drcoptions; /* configurable DRC options */
/* internal stuff */
@@ -655,8 +656,8 @@ private:
void generate_badcop(drcuml_block &block, const int cop);
void log_add_disasm_comment(drcuml_block &block, uint32_t pc, uint32_t op);
- const char *log_desc_flags_to_string(uint32_t flags);
- void log_register_list(const char *string, const uint32_t *reglist, const uint32_t *regnostarlist);
+ const char *log_desc_flags_to_string(opcode_desc const &desc);
+ void log_register_list(const char *string, const std::bitset<68> &reglist, const std::bitset<68> *regnostarlist);
void log_opcode_desc(const opcode_desc *desclist, int indent);
void load_elf();
@@ -1011,31 +1012,6 @@ public:
};
-
-class mips3_frontend : public drc_frontend {
-public:
- // construction/destruction
- mips3_frontend(mips3_device *mips3, uint32_t window_start, uint32_t window_end, uint32_t max_sequence);
-
-protected:
- // required overrides
- virtual bool describe(opcode_desc &desc, const opcode_desc *prev) override;
-
-private:
- // internal helpers
- bool describe_special(uint32_t op, opcode_desc &desc);
- bool describe_regimm(uint32_t op, opcode_desc &desc);
- bool describe_idt(uint32_t op, opcode_desc &desc);
- bool describe_cop0(uint32_t op, opcode_desc &desc);
- bool describe_cop1(uint32_t op, opcode_desc &desc);
- bool describe_cop1x(uint32_t op, opcode_desc &desc);
- bool describe_cop2(uint32_t op, opcode_desc &desc);
-
- // internal state
- mips3_device *m_mips3;
-};
-
-
/***************************************************************************
COMPILER-SPECIFIC OPTIONS
***************************************************************************/
diff --git a/src/devices/cpu/mips/mips3drc.cpp b/src/devices/cpu/mips/mips3drc.cpp
index f682da6b212..383c90529d0 100644
--- a/src/devices/cpu/mips/mips3drc.cpp
+++ b/src/devices/cpu/mips/mips3drc.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Aaron Giles
/***************************************************************************
- mips3drc.c
+ mips3drc.cpp
Universal machine language-based MIPS III/IV emulator.
@@ -24,11 +24,13 @@
***************************************************************************/
#include "emu.h"
+#include "mips3.h"
+
#include "mips3com.h"
#include "mips3fe.h"
#include "mips3dsm.h"
#include "ps2vu.h"
-#include "cpu/drcfe.h"
+
#include "cpu/drcuml.h"
#include "cpu/drcumlsh.h"
@@ -93,17 +95,6 @@ static const uint8_t fcc_shift[8] = { 23, 25, 26, 27, 28, 29, 30, 31 };
***************************************************************************/
/*-------------------------------------------------
- epc - compute the exception PC from a
- descriptor
--------------------------------------------------*/
-
-static inline uint32_t epc(const opcode_desc *desc)
-{
- return (desc->flags & OPFLAG_IN_DELAY_SLOT) ? (desc->pc - 3) : desc->pc;
-}
-
-
-/*-------------------------------------------------
alloc_handle - allocate a handle if not
already allocated
-------------------------------------------------*/
@@ -340,7 +331,7 @@ void mips3_device::code_compile_block(uint8_t mode, offs_t pc)
/* determine the last instruction in this sequence */
for (seqlast = seqhead; seqlast != nullptr; seqlast = seqlast->next())
- if (seqlast->flags & OPFLAG_END_SEQUENCE)
+ if (seqlast->end_sequence())
break;
assert(seqlast != nullptr);
@@ -370,7 +361,7 @@ void mips3_device::code_compile_block(uint8_t mode, offs_t pc)
generate_checksum_block(block, compiler, seqhead, seqlast, codelast);
/* label this instruction, if it may be jumped to locally */
- if (seqhead->flags & OPFLAG_IS_BRANCH_TARGET)
+ if (seqhead->is_branch_target())
{
UML_LABEL(block, seqhead->pc | 0x80000000); // label seqhead->pc | 0x80000000
}
@@ -382,7 +373,7 @@ void mips3_device::code_compile_block(uint8_t mode, offs_t pc)
}
/* if we need to return to the start, do it */
- if (seqlast->flags & OPFLAG_RETURN_TO_START)
+ if (seqlast->return_to_start())
nextpc = pc;
/* otherwise we just go to the next instruction */
@@ -393,7 +384,7 @@ void mips3_device::code_compile_block(uint8_t mode, offs_t pc)
generate_update_cycles(block, compiler, nextpc, true); // <subtract cycles>
/* if the last instruction can change modes, use a variable mode; otherwise, assume the same mode */
- if (seqlast->flags & OPFLAG_CAN_CHANGE_MODES)
+ if (seqlast->can_change_modes())
{
UML_HASHJMP(block, mem(&m_core->mode), nextpc, *m_nocode); // hashjmp <mode>,nextpc,nocode
}
@@ -1155,18 +1146,18 @@ void mips3_device::generate_checksum_block(drcuml_block &block, compiler_state &
if (m_drcuml->logging())
block.append_comment("[Validation for %08X]", seqhead->pc); // comment
- /* loose verify or single instruction: just compare and fail */
if (!(m_drcoptions & MIPS3DRC_STRICT_VERIFY) || seqhead->next() == nullptr)
{
- if (!(seqhead->flags & OPFLAG_VIRTUAL_NOOP))
+ // loose verify or single instruction: just compare and fail
+ if (!seqhead->virtual_noop())
{
- uint32_t sum = seqhead->opptr.l[0];
+ uint32_t sum = seqhead->opptr;
const void *base = m_prptr(seqhead->physpc);
uint32_t low_bits = (seqhead->physpc & (m_data_bits == 64 ? 4 : 0)) ^ m_dword_xor;
UML_LOAD(block, I0, base, low_bits, SIZE_DWORD, SCALE_x1); // load i0,base,0,dword
if (seqhead->delay.first() != nullptr
- && !(seqhead->delay.first()->flags & OPFLAG_VIRTUAL_NOOP)
+ && !seqhead->delay.first()->virtual_noop()
&& seqhead->physpc != seqhead->delay.first()->physpc)
{
uint32_t low_bits = (seqhead->delay.first()->physpc & (m_data_bits == 64 ? 4 : 0)) ^ m_dword_xor;
@@ -1175,26 +1166,27 @@ void mips3_device::generate_checksum_block(drcuml_block &block, compiler_state &
UML_LOAD(block, I1, base, low_bits, SIZE_DWORD, SCALE_x1); // load i1,base,dword
UML_ADD(block, I0, I0, I1); // add i0,i0,i1
- sum += seqhead->delay.first()->opptr.l[0];
+ sum += seqhead->delay.first()->opptr;
}
- UML_CMP(block, I0, sum); // cmp i0,opptr[0]
- UML_EXHc(block, COND_NE, *m_nocode, epc(seqhead)); // exne nocode,seqhead->pc
+ UML_CMP(block, I0, sum); // cmp i0,opptr
+ UML_EXHc(block, COND_NE, *m_nocode, seqhead->epc()); // exne nocode,seqhead->pc
}
}
-
- /* full verification; sum up everything */
else
{
+ // full verification; sum up everything
#if 0
for (curdesc = seqhead->next(); curdesc != seqlast->next(); curdesc = curdesc->next())
- if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP))
+ {
+ if (!curdesc->virtual_noop())
{
const void *base = m_prptr(seqhead->physpc);
UML_LOAD(block, I0, base, m_dword_xor, SIZE_DWORD, SCALE_x1); // load i0,base,0,dword
- UML_CMP(block, I0, curdesc->opptr.l[0]); // cmp i0,opptr[0]
+ UML_CMP(block, I0, curdesc->opptr); // cmp i0,opptr
UML_EXHc(block, COND_NE, *m_nocode, epc(seqhead)); // exne nocode,seqhead->pc
}
+ }
#else
uint32_t sum = 0;
const void *base = m_prptr(seqhead->physpc);
@@ -1202,31 +1194,31 @@ void mips3_device::generate_checksum_block(drcuml_block &block, compiler_state &
const uint32_t last_physpc = codelast->physpc;
uint32_t low_bits = (seqhead->physpc & data_bits_mask) ^ m_dword_xor;
UML_LOAD(block, I0, base, low_bits, SIZE_DWORD, SCALE_x1); // load i0,base,0,dword
- sum += seqhead->opptr.l[0];
- if ((m_drcoptions & MIPS3DRC_EXTRA_INSTR_CHECK) && !(codelast->flags & OPFLAG_VIRTUAL_NOOP) && last_physpc != seqhead->physpc)
+ sum += seqhead->opptr;
+ if ((m_drcoptions & MIPS3DRC_EXTRA_INSTR_CHECK) && !codelast->virtual_noop() && last_physpc != seqhead->physpc)
{
base = m_prptr(last_physpc);
assert(base != nullptr);
low_bits = (last_physpc & data_bits_mask) ^ m_dword_xor;
UML_LOAD(block, I1, base, low_bits, SIZE_DWORD, SCALE_x1); // load i1,base,dword
UML_ADD(block, I0, I0, I1); // add i0,i0,i1
- sum += codelast->opptr.l[0];
+ sum += codelast->opptr;
}
if (!(m_drcoptions & MIPS3DRC_EXTRA_INSTR_CHECK))
{
for (curdesc = seqhead->next(); curdesc != seqlast->next(); curdesc = curdesc->next())
{
- if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP))
+ if (!curdesc->virtual_noop())
{
base = m_prptr(curdesc->physpc);
assert(base != nullptr);
low_bits = (curdesc->physpc & data_bits_mask) ^ m_dword_xor;
UML_LOAD(block, I1, base, low_bits, SIZE_DWORD, SCALE_x1); // load i1,base,dword
UML_ADD(block, I0, I0, I1); // add i0,i0,i1
- sum += curdesc->opptr.l[0];
+ sum += curdesc->opptr;
if (curdesc->delay.first() != nullptr
- && !(curdesc->delay.first()->flags & OPFLAG_VIRTUAL_NOOP)
+ && !curdesc->delay.first()->virtual_noop()
&& (curdesc == seqlast || (curdesc->next() != nullptr && curdesc->next()->physpc != curdesc->delay.first()->physpc)))
{
base = m_prptr(curdesc->delay.first()->physpc);
@@ -1234,7 +1226,7 @@ void mips3_device::generate_checksum_block(drcuml_block &block, compiler_state &
low_bits = (curdesc->delay.first()->physpc & data_bits_mask) ^ m_dword_xor;
UML_LOAD(block, I1, base, low_bits, SIZE_DWORD, SCALE_x1); // load i1,base,dword
UML_ADD(block, I0, I0, I1); // add i0,i0,i1
- sum += curdesc->delay.first()->opptr.l[0];
+ sum += curdesc->delay.first()->opptr;
}
}
}
@@ -1243,7 +1235,7 @@ void mips3_device::generate_checksum_block(drcuml_block &block, compiler_state &
{
for (curdesc = seqhead->next(); curdesc != seqlast->next(); curdesc = curdesc->next())
{
- if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP))
+ if (!curdesc->virtual_noop())
{
// Skip the last if it was already included above
if (curdesc->physpc != last_physpc)
@@ -1253,11 +1245,11 @@ void mips3_device::generate_checksum_block(drcuml_block &block, compiler_state &
low_bits = (curdesc->physpc & data_bits_mask) ^ m_dword_xor;
UML_LOAD(block, I1, base, low_bits, SIZE_DWORD, SCALE_x1); // load i1,base,dword
UML_ADD(block, I0, I0, I1); // add i0,i0,i1
- sum += curdesc->opptr.l[0];
+ sum += curdesc->opptr;
}
if (curdesc->delay.first() != nullptr
- && !(curdesc->delay.first()->flags & OPFLAG_VIRTUAL_NOOP)
+ && !curdesc->delay.first()->virtual_noop()
&& (curdesc == seqlast || (curdesc->next() != nullptr && curdesc->next()->physpc != curdesc->delay.first()->physpc)))
{
base = m_prptr(curdesc->delay.first()->physpc);
@@ -1265,13 +1257,13 @@ void mips3_device::generate_checksum_block(drcuml_block &block, compiler_state &
low_bits = (curdesc->delay.first()->physpc & data_bits_mask) ^ m_dword_xor;
UML_LOAD(block, I1, base, low_bits, SIZE_DWORD, SCALE_x1); // load i1,base,dword
UML_ADD(block, I0, I0, I1); // add i0,i0,i1
- sum += curdesc->delay.first()->opptr.l[0];
+ sum += curdesc->delay.first()->opptr;
}
}
}
}
UML_CMP(block, I0, sum); // cmp i0,sum
- UML_EXHc(block, COND_NE, *m_nocode, epc(seqhead)); // exne nocode,seqhead->pc
+ UML_EXHc(block, COND_NE, *m_nocode, seqhead->epc()); // exne nocode,seqhead->pc
if (DEBUG_STRICT_VERIFY)
{
// This code will do additional checks on the last instruction and last delay slot and indicate if the check failed
@@ -1279,13 +1271,13 @@ void mips3_device::generate_checksum_block(drcuml_block &block, compiler_state &
uml::code_label check_failed = compiler.labelnum++;
uml::code_label check_passed = compiler.labelnum++;
// Check the last instruction
- if (!(codelast->flags & OPFLAG_VIRTUAL_NOOP) && last_physpc != seqhead->physpc)
+ if (!codelast->virtual_noop() && (last_physpc != seqhead->physpc))
{
base = m_prptr(last_physpc);
assert(base != nullptr);
low_bits = (last_physpc & (m_data_bits == 64 ? 4 : 0)) ^ m_dword_xor;
UML_LOAD(block, I0, base, low_bits, SIZE_DWORD, SCALE_x1); // load i1,base,dword
- sum = codelast->opptr.l[0];
+ sum = codelast->opptr;
UML_CMP(block, I0, sum); // cmp i0,sum
UML_JMPc(block, COND_E, check_second);
static const char text[] = "Last instr validation fail seq: %08X end: %08x\n";
@@ -1298,14 +1290,14 @@ void mips3_device::generate_checksum_block(drcuml_block &block, compiler_state &
UML_JMP(block, check_failed);
// Check the last instruction delay slot
UML_LABEL(block, check_second);
- if (codelast->delay.first() != nullptr && !(codelast->delay.first()->flags & OPFLAG_VIRTUAL_NOOP)
+ if (codelast->delay.first() != nullptr && !codelast->delay.first()->virtual_noop()
&& last_physpc != seqhead->physpc)
{
base = m_prptr(codelast->delay.first()->physpc);
assert(base != nullptr);
low_bits = (codelast->delay.first()->physpc & (m_data_bits == 64 ? 4 : 0)) ^ m_dword_xor;
UML_LOAD(block, I0, base, low_bits, SIZE_DWORD, SCALE_x1); // load i1,base,dword
- sum = codelast->delay.first()->opptr.l[0];
+ sum = codelast->delay.first()->opptr;
UML_CMP(block, I0, sum); // cmp i0,sum
UML_JMPc(block, COND_E, check_passed);
static const char text[] = "Last delay slot validation fail seq: %08X end: %08x\n";
@@ -1319,7 +1311,7 @@ void mips3_device::generate_checksum_block(drcuml_block &block, compiler_state &
}
UML_JMP(block, check_passed);
UML_LABEL(block, check_failed);
- UML_EXH(block, *m_nocode, epc(seqhead)); // exne nocode,seqhead->pc
+ UML_EXH(block, *m_nocode, seqhead->epc()); // exne nocode,seqhead->pc
UML_LABEL(block, check_passed);
}
#endif
@@ -1335,11 +1327,11 @@ void mips3_device::generate_checksum_block(drcuml_block &block, compiler_state &
void mips3_device::generate_sequence_instruction(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc)
{
/* add an entry for the log */
- if (m_drcuml->logging() && !(desc->flags & OPFLAG_VIRTUAL_NOOP))
- log_add_disasm_comment(block, desc->pc, desc->opptr.l[0]);
+ if (m_drcuml->logging() && !desc->virtual_noop())
+ log_add_disasm_comment(block, desc->pc, desc->opptr);
/* set the PC map variable */
- offs_t expc = (desc->flags & OPFLAG_IN_DELAY_SLOT) ? desc->pc - 3 : desc->pc;
+ const offs_t expc = desc->epc();
UML_MAPVAR(block, MAPVAR_PC, expc); // mapvar PC,expc
/* accumulate total cycles */
@@ -1347,7 +1339,7 @@ void mips3_device::generate_sequence_instruction(drcuml_block &block, compiler_s
/* is this a hotspot? */
for (int hotnum = 0; hotnum < MIPS3_MAX_HOTSPOTS; hotnum++)
- if (m_hotspot[hotnum].pc != 0 && desc->pc == m_hotspot[hotnum].pc && desc->opptr.l[0] == m_hotspot[hotnum].opcode)
+ if (m_hotspot[hotnum].pc != 0 && desc->pc == m_hotspot[hotnum].pc && desc->opptr == m_hotspot[hotnum].opcode)
{
compiler.cycles += m_hotspot[hotnum].cycles;
break;
@@ -1372,7 +1364,7 @@ void mips3_device::generate_sequence_instruction(drcuml_block &block, compiler_s
}
/* if we hit an unmapped address, fatal error */
- if (desc->flags & OPFLAG_COMPILER_UNMAPPED)
+ if (desc->compiler_unmapped())
{
UML_MOV(block, mem(&m_core->pc), desc->pc); // mov [pc],desc->pc
save_fast_iregs(block);
@@ -1380,7 +1372,7 @@ void mips3_device::generate_sequence_instruction(drcuml_block &block, compiler_s
}
/* if we hit a compiler page fault, it's just like a TLB mismatch */
- if (desc->flags & OPFLAG_COMPILER_PAGE_FAULT)
+ if (desc->compiler_page_fault())
{
if (PRINTF_MMU)
{
@@ -1395,7 +1387,7 @@ void mips3_device::generate_sequence_instruction(drcuml_block &block, compiler_s
}
/* validate our TLB entry at this PC; if we fail, we need to handle it */
- if ((desc->flags & OPFLAG_VALIDATE_TLB) && (desc->pc < 0x80000000 || desc->pc >= 0xc0000000))
+ if (desc->validate_tlb() && (desc->pc < 0x80000000 || desc->pc >= 0xc0000000))
{
const vtlb_entry *tlbtable = vtlb_table();
@@ -1430,18 +1422,19 @@ void mips3_device::generate_sequence_instruction(drcuml_block &block, compiler_s
}
}
- /* if this is an invalid opcode, generate the exception now */
- if (desc->flags & OPFLAG_INVALID_OPCODE)
+ if (desc->invalid_opcode())
+ {
+ // if this is an invalid opcode, generate the exception now
UML_EXH(block, *m_exception[EXCEPTION_INVALIDOP], 0); // exh invalidop,0
-
- /* otherwise, unless this is a virtual no-op, it's a regular instruction */
- else if (!(desc->flags & OPFLAG_VIRTUAL_NOOP))
+ }
+ else if (!desc->virtual_noop())
{
- /* compile the instruction */
+ // otherwise, unless this is a virtual no-op, it's a regular instruction
+ // compile the instruction
if (!generate_opcode(block, compiler, desc))
{
UML_MOV(block, mem(&m_core->pc), desc->pc); // mov [pc],desc->pc
- UML_MOV(block, mem(&m_core->arg0), desc->opptr.l[0]); // mov [arg0],desc->opptr.l
+ UML_MOV(block, mem(&m_core->arg0), desc->opptr); // mov [arg0],desc->opptr
UML_CALLC(block, cfunc_unimplemented, this); // callc cfunc_unimplemented
}
}
@@ -1455,7 +1448,7 @@ void mips3_device::generate_sequence_instruction(drcuml_block &block, compiler_s
void mips3_device::generate_delay_slot_and_branch(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint8_t linkreg)
{
compiler_state compiler_temp(compiler);
- uint32_t op = desc->opptr.l[0];
+ const uint32_t op = desc->opptr;
/* fetch the target register if dynamic, in case it is modified by the delay slot */
if (desc->targetpc == BRANCH_TARGET_DYNAMIC)
@@ -1478,7 +1471,7 @@ void mips3_device::generate_delay_slot_and_branch(drcuml_block &block, compiler_
if (desc->targetpc != BRANCH_TARGET_DYNAMIC)
{
generate_update_cycles(block, compiler_temp, desc->targetpc, true); // <subtract cycles>
- if (!(m_drcoptions & MIPS3DRC_DISABLE_INTRABLOCK) && (desc->flags & OPFLAG_INTRABLOCK_BRANCH))
+ if (!(m_drcoptions & MIPS3DRC_DISABLE_INTRABLOCK) && desc->intrablock_branch())
{
UML_JMP(block, desc->targetpc | 0x80000000); // jmp desc->targetpc | 0x80000000
}
@@ -1509,9 +1502,9 @@ void mips3_device::generate_delay_slot_and_branch(drcuml_block &block, compiler_
bool mips3_device::generate_opcode(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc)
{
- int in_delay_slot = ((desc->flags & OPFLAG_IN_DELAY_SLOT) != 0);
- uint32_t op = desc->opptr.l[0];
- uint8_t opswitch = op >> 26;
+ const int in_delay_slot = desc->in_delay_slot();
+ const uint32_t op = desc->opptr;
+ const uint8_t opswitch = op >> 26;
uml::code_label skip;
switch (opswitch)
@@ -2047,8 +2040,8 @@ bool mips3_device::generate_opcode(drcuml_block &block, compiler_state &compiler
bool mips3_device::generate_special(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc)
{
- uint32_t op = desc->opptr.l[0];
- uint8_t opswitch = op & 63;
+ const uint32_t op = desc->opptr;
+ const uint8_t opswitch = op & 63;
switch (opswitch)
{
@@ -2440,8 +2433,8 @@ bool mips3_device::generate_special(drcuml_block &block, compiler_state &compile
bool mips3_device::generate_regimm(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc)
{
- uint32_t op = desc->opptr.l[0];
- uint8_t opswitch = RTREG;
+ const uint32_t op = desc->opptr;
+ const uint8_t opswitch = RTREG;
uml::code_label skip;
switch (opswitch)
@@ -2527,8 +2520,8 @@ bool mips3_device::generate_regimm(drcuml_block &block, compiler_state &compiler
bool mips3_device::generate_idt(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc)
{
- uint32_t op = desc->opptr.l[0];
- uint8_t opswitch = op & 0x1f;
+ const uint32_t op = desc->opptr;
+ const uint8_t opswitch = op & 0x1f;
/* only enabled on IDT processors */
if (m_flavor != MIPS3_TYPE_R4650)
@@ -2577,7 +2570,7 @@ bool mips3_device::generate_idt(drcuml_block &block, compiler_state &compiler, c
bool mips3_device::generate_set_cop0_reg(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint8_t reg)
{
- int in_delay_slot = ((desc->flags & OPFLAG_IN_DELAY_SLOT) != 0);
+ const int in_delay_slot = desc->in_delay_slot();
uml::code_label link;
switch (reg)
@@ -2729,8 +2722,8 @@ void mips3_device::check_cop0_access(drcuml_block &block)
bool mips3_device::generate_cop0(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc)
{
- uint32_t op = desc->opptr.l[0];
- uint8_t opswitch = RSREG;
+ const uint32_t op = desc->opptr;
+ const uint8_t opswitch = RSREG;
int skip;
/* generate an exception if COP0 is disabled unless we are in kernel mode */
@@ -2865,7 +2858,7 @@ void mips3_device::check_cop1_access(drcuml_block &block)
bool mips3_device::generate_cop1(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc)
{
- uint32_t op = desc->opptr.l[0];
+ const uint32_t op = desc->opptr;
uml::code_label skip;
uml::condition_t condition;
@@ -3386,8 +3379,8 @@ bool mips3_device::generate_cop1(drcuml_block &block, compiler_state &compiler,
bool mips3_device::generate_cop1x(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc)
{
- int in_delay_slot = ((desc->flags & OPFLAG_IN_DELAY_SLOT) != 0);
- uint32_t op = desc->opptr.l[0];
+ const int in_delay_slot = desc->in_delay_slot();
+ const uint32_t op = desc->opptr;
check_cop1_access(block);
@@ -3505,52 +3498,52 @@ void mips3_device::log_add_disasm_comment(drcuml_block &block, uint32_t pc, uint
flags
-------------------------------------------------*/
-const char *mips3_device::log_desc_flags_to_string(uint32_t flags)
+const char *mips3_device::log_desc_flags_to_string(opcode_desc const &desc)
{
static char tempbuf[30];
char *dest = tempbuf;
/* branches */
- if (flags & OPFLAG_IS_UNCONDITIONAL_BRANCH)
+ if (desc.is_unconditional_branch())
*dest++ = 'U';
- else if (flags & OPFLAG_IS_CONDITIONAL_BRANCH)
+ else if (desc.is_conditional_branch())
*dest++ = 'C';
else
*dest++ = '.';
/* intrablock branches */
- *dest++ = (flags & OPFLAG_INTRABLOCK_BRANCH) ? 'i' : '.';
+ *dest++ = desc.intrablock_branch() ? 'i' : '.';
/* branch targets */
- *dest++ = (flags & OPFLAG_IS_BRANCH_TARGET) ? 'B' : '.';
+ *dest++ = desc.is_branch_target() ? 'B' : '.';
/* delay slots */
- *dest++ = (flags & OPFLAG_IN_DELAY_SLOT) ? 'D' : '.';
+ *dest++ = desc.in_delay_slot() ? 'D' : '.';
/* exceptions */
- if (flags & OPFLAG_WILL_CAUSE_EXCEPTION)
+ if (desc.will_cause_exception())
*dest++ = 'E';
- else if (flags & OPFLAG_CAN_CAUSE_EXCEPTION)
+ else if (desc.can_cause_exception())
*dest++ = 'e';
else
*dest++ = '.';
/* read/write */
- if (flags & OPFLAG_READS_MEMORY)
+ if (desc.reads_memory())
*dest++ = 'R';
- else if (flags & OPFLAG_WRITES_MEMORY)
+ else if (desc.writes_memory())
*dest++ = 'W';
else
*dest++ = '.';
/* TLB validation */
- *dest++ = (flags & OPFLAG_VALIDATE_TLB) ? 'V' : '.';
+ *dest++ = desc.validate_tlb() ? 'V' : '.';
/* TLB modification */
- *dest++ = (flags & OPFLAG_MODIFIES_TRANSLATION) ? 'T' : '.';
+ *dest++ = desc.modifies_translation() ? 'T' : '.';
/* redispatch */
- *dest++ = (flags & OPFLAG_REDISPATCH) ? 'R' : '.';
+ *dest++ = desc.redispatch() ? 'R' : '.';
return tempbuf;
}
@@ -3559,49 +3552,52 @@ const char *mips3_device::log_desc_flags_to_string(uint32_t flags)
log_register_list - log a list of GPR registers
-------------------------------------------------*/
-void mips3_device::log_register_list(const char *string, const uint32_t *reglist, const uint32_t *regnostarlist)
+void mips3_device::log_register_list(const char *string, const std::bitset<68> &reglist, const std::bitset<68> *regnostarlist)
{
int count = 0;
- int regnum;
/* skip if nothing */
- if (reglist[0] == 0 && reglist[1] == 0 && reglist[2] == 0)
+ if (reglist.none())
return;
m_drcuml->log_printf("[%s:", string);
- for (regnum = 1; regnum < 32; regnum++)
- if (reglist[0] & REGFLAG_R(regnum))
+ for (int regnum = 1; regnum < 32; regnum++)
+ {
+ if (reglist[opcode_desc::REG_FLAG_R0 + regnum])
{
m_drcuml->log_printf("%sr%d", (count++ == 0) ? "" : ",", regnum);
- if (regnostarlist != nullptr && !(regnostarlist[0] & REGFLAG_R(regnum)))
+ if (regnostarlist && !(*regnostarlist)[opcode_desc::REG_FLAG_R0 + regnum])
m_drcuml->log_printf("*");
}
+ }
- for (regnum = 0; regnum < 32; regnum++)
- if (reglist[1] & REGFLAG_CPR1(regnum))
+ for (int regnum = 0; regnum < 32; regnum++)
+ {
+ if (reglist[opcode_desc::REG_FLAG_CPR10 + regnum])
{
m_drcuml->log_printf("%sfr%d", (count++ == 0) ? "" : ",", regnum);
- if (regnostarlist != nullptr && !(regnostarlist[1] & REGFLAG_CPR1(regnum)))
+ if (regnostarlist && !(*regnostarlist)[opcode_desc::REG_FLAG_CPR10 + regnum])
m_drcuml->log_printf("*");
}
+ }
- if (reglist[2] & REGFLAG_LO)
+ if (reglist[opcode_desc::REG_FLAG_LO])
{
m_drcuml->log_printf("%slo", (count++ == 0) ? "" : ",");
- if (regnostarlist != nullptr && !(regnostarlist[2] & REGFLAG_LO))
+ if (regnostarlist && !(*regnostarlist)[opcode_desc::REG_FLAG_LO])
m_drcuml->log_printf("*");
}
- if (reglist[2] & REGFLAG_HI)
+ if (reglist[opcode_desc::REG_FLAG_HI])
{
m_drcuml->log_printf("%shi", (count++ == 0) ? "" : ",");
- if (regnostarlist != nullptr && !(regnostarlist[2] & REGFLAG_HI))
+ if (regnostarlist && !(*regnostarlist)[opcode_desc::REG_FLAG_HI])
m_drcuml->log_printf("*");
}
- if (reglist[2] & REGFLAG_FCC)
+ if (reglist[opcode_desc::REG_FLAG_FCC])
{
m_drcuml->log_printf("%sfcc", (count++ == 0) ? "" : ",");
- if (regnostarlist != nullptr && !(regnostarlist[2] & REGFLAG_FCC))
+ if (regnostarlist && !(*regnostarlist)[opcode_desc::REG_FLAG_FCC])
m_drcuml->log_printf("*");
}
@@ -3627,23 +3623,23 @@ void mips3_device::log_opcode_desc(const opcode_desc *desclist, int indent)
/* disassemle the current instruction and output it to the log */
if (m_drcuml->logging() || m_drcuml->logging_native())
{
- if (desclist->flags & OPFLAG_VIRTUAL_NOOP)
+ if (desclist->virtual_noop())
buffer << "<virtual nop>";
else
{
mips3_disassembler mips3d;
- mips3d.dasm_one(buffer, desclist->pc, desclist->opptr.l[0]);
+ mips3d.dasm_one(buffer, desclist->pc, desclist->opptr);
}
}
else
buffer << "???";
const std::string buffer_string = buffer.str();
- m_drcuml->log_printf("%08X [%08X] t:%08X f:%s: %-30s", desclist->pc, desclist->physpc, desclist->targetpc, log_desc_flags_to_string(desclist->flags), buffer_string.c_str());
+ m_drcuml->log_printf("%08X [%08X] t:%08X f:%s: %-30s", desclist->pc, desclist->physpc, desclist->targetpc, log_desc_flags_to_string(*desclist), buffer_string.c_str());
/* output register states */
log_register_list("use", desclist->regin, nullptr);
- log_register_list("mod", desclist->regout, desclist->regreq);
+ log_register_list("mod", desclist->regout, &desclist->regreq);
m_drcuml->log_printf("\n");
/* if we have a delay slot, output it recursively */
@@ -3651,7 +3647,7 @@ void mips3_device::log_opcode_desc(const opcode_desc *desclist, int indent)
log_opcode_desc(desclist->delay.first(), indent + 1);
/* at the end of a sequence add a dividing line */
- if (desclist->flags & OPFLAG_END_SEQUENCE)
+ if (desclist->end_sequence())
m_drcuml->log_printf("-----\n");
}
}
diff --git a/src/devices/cpu/mips/mips3fe.cpp b/src/devices/cpu/mips/mips3fe.cpp
index 49b86be681b..9984626f760 100644
--- a/src/devices/cpu/mips/mips3fe.cpp
+++ b/src/devices/cpu/mips/mips3fe.cpp
@@ -10,8 +10,10 @@
#include "emu.h"
#include "mips3fe.h"
+
#include "mips3com.h"
-#include "ps2vu.h"
+
+#include "cpu/drcfe.ipp"
//**************************************************************************
@@ -22,22 +24,31 @@
// mips3_frontend - constructor
//-------------------------------------------------
-mips3_frontend::mips3_frontend(mips3_device *mips3, uint32_t window_start, uint32_t window_end, uint32_t max_sequence)
- : drc_frontend(*mips3, window_start, window_end, max_sequence),
- m_mips3(mips3)
+mips3_device::frontend::frontend(mips3_device *mips3, uint32_t window_start, uint32_t window_end, uint32_t max_sequence)
+ : drc_frontend_base(mips3->space_config(AS_PROGRAM)->page_shift(), window_start, window_end, max_sequence)
+ , m_mips3(mips3)
{
}
+mips3_device::frontend::~frontend()
+{
+}
+
+mips3_device::opcode_desc const *mips3_device::frontend::describe_code(offs_t startpc)
+{
+ return do_describe_code(
+ [this] (opcode_desc &desc, opcode_desc const *prev) { return describe(desc, prev); },
+ startpc);
+}
+
//-------------------------------------------------
// describe - build a description of a single
// instruction
//-------------------------------------------------
-bool mips3_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
+bool mips3_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev)
{
- uint32_t op, opswitch;
-
// compute the physical PC
assert((desc.physpc & 3) == 0);
address_space *tspace;
@@ -45,20 +56,24 @@ bool mips3_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
{
// uh-oh: a page fault; leave the description empty and just if this is the first instruction, leave it empty and
// mark as needing to validate; otherwise, just end the sequence here
- desc.flags |= OPFLAG_VALIDATE_TLB | OPFLAG_CAN_CAUSE_EXCEPTION | OPFLAG_COMPILER_PAGE_FAULT | OPFLAG_VIRTUAL_NOOP | OPFLAG_END_SEQUENCE;
+ desc.set_validate_tlb();
+ desc.set_can_cause_exception();
+ desc.set_compiler_page_fault();
+ desc.set_virtual_noop();
+ desc.set_end_sequence();
return true;
}
// fetch the opcode
assert((desc.physpc & 3) == 0);
- op = desc.opptr.l[0] = m_mips3->m_pr32(desc.physpc);
+ const uint32_t op = desc.opptr = m_mips3->m_pr32(desc.physpc);
// all instructions are 4 bytes and default to a single cycle each
desc.length = 4;
desc.cycles = 1;
// parse the instruction
- opswitch = op >> 26;
+ const uint32_t opswitch = op >> 26;
switch (opswitch)
{
case 0x00: // SPECIAL
@@ -85,14 +100,16 @@ bool mips3_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
return describe_idt(op, desc);
case 0x02: // J
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
desc.targetpc = (desc.pc & 0xf0000000) | (LIMMVAL << 2);
desc.delayslots = 1;
return true;
case 0x03: // JAL
- desc.regout[0] |= REGFLAG_R(31);
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.set_r_modified(31);
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
desc.targetpc = (desc.pc & 0xf0000000) | (LIMMVAL << 2);
desc.delayslots = 1;
return true;
@@ -102,11 +119,15 @@ bool mips3_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
case 0x14: // BEQL
case 0x15: // BNEL
if ((opswitch == 0x04 || opswitch == 0x14) && RSREG == RTREG)
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ {
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
+ }
else
{
- desc.regin[0] |= REGFLAG_R(RSREG) | REGFLAG_R(RTREG);
- desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+ desc.set_r_used(RSREG);
+ desc.set_r_used(RTREG);
+ desc.set_is_conditional_branch();
}
desc.targetpc = desc.pc + 4 + SIMMVAL * 4;
desc.delayslots = 1;
@@ -118,11 +139,14 @@ bool mips3_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
case 0x16: // BLEZL
case 0x17: // BGTZL
if ((opswitch == 0x06 || opswitch == 0x16) && RSREG == 0)
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ {
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
+ }
else
{
- desc.regin[0] |= REGFLAG_R(RSREG);
- desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+ desc.set_r_used(RSREG);
+ desc.set_is_conditional_branch();
}
desc.targetpc = desc.pc + 4 + SIMMVAL * 4;
desc.delayslots = 1;
@@ -131,9 +155,9 @@ bool mips3_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
case 0x08: // ADDI
case 0x18: // DADDI
- desc.regin[0] |= REGFLAG_R(RSREG);
- desc.regout[0] |= REGFLAG_R(RTREG);
- desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.set_r_used(RSREG);
+ desc.set_r_modified(RTREG);
+ desc.set_can_cause_exception();
return true;
case 0x09: // ADDIU
@@ -143,19 +167,19 @@ bool mips3_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
case 0x0d: // ORI
case 0x0e: // XORI
case 0x19: // DADDIU
- desc.regin[0] |= REGFLAG_R(RSREG);
- desc.regout[0] |= REGFLAG_R(RTREG);
+ desc.set_r_used(RSREG);
+ desc.set_r_modified(RTREG);
return true;
case 0x0f: // LUI
- desc.regout[0] |= REGFLAG_R(RTREG);
+ desc.set_r_modified(RTREG);
return true;
case 0x1a: // LDL
case 0x1b: // LDR
case 0x22: // LWL
case 0x26: // LWR
- desc.regin[0] |= REGFLAG_R(RTREG);
+ desc.set_r_used(RTREG);
[[fallthrough]];
case 0x20: // LB
case 0x21: // LH
@@ -166,9 +190,10 @@ bool mips3_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
case 0x30: // LL
case 0x34: // LLD
case 0x37: // LD
- desc.regin[0] |= REGFLAG_R(RSREG);
- desc.regout[0] |= REGFLAG_R(RTREG);
- desc.flags |= OPFLAG_READS_MEMORY | OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.set_r_used(RSREG);
+ desc.set_r_modified(RTREG);
+ desc.set_reads_memory();
+ desc.set_can_cause_exception();
return true;
case 0x28: // SB
@@ -179,41 +204,49 @@ bool mips3_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
case 0x2d: // SDR
case 0x2e: // SWR
case 0x3f: // SD
- desc.regin[0] |= REGFLAG_R(RSREG) | REGFLAG_R(RTREG);
- desc.flags |= OPFLAG_WRITES_MEMORY | OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.set_r_used(RSREG);
+ desc.set_r_used(RTREG);
+ desc.set_writes_memory();
+ desc.set_can_cause_exception();
return true;
case 0x38: // SC
case 0x3c: // SCD
- desc.regin[0] |= REGFLAG_R(RSREG) | REGFLAG_R(RTREG);
- desc.regout[0] |= REGFLAG_R(RTREG);
- desc.flags |= OPFLAG_WRITES_MEMORY | OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.set_r_used(RSREG);
+ desc.set_r_used(RTREG);
+ desc.set_r_modified(RTREG);
+ desc.set_writes_memory();
+ desc.set_can_cause_exception();
return true;
case 0x31: // LWC1
case 0x35: // LDC1
- desc.regin[0] |= REGFLAG_R(RSREG);
- desc.regout[1] |= REGFLAG_CPR1(RTREG);
- desc.flags |= OPFLAG_READS_MEMORY | OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.set_r_used(RSREG);
+ desc.set_cpr1_modified(RTREG);
+ desc.set_reads_memory();
+ desc.set_can_cause_exception();
return true;
case 0x39: // SWC1
case 0x3d: // SDC1
- desc.regin[0] |= REGFLAG_R(RSREG);
- desc.regin[1] |= REGFLAG_CPR1(RTREG);
- desc.flags |= OPFLAG_WRITES_MEMORY | OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.set_r_used(RSREG);
+ desc.set_cpr1_used(RTREG);
+ desc.set_writes_memory();
+ desc.set_can_cause_exception();
return true;
case 0x32: // LWC2
case 0x36: // LDC2
- desc.regin[0] |= REGFLAG_R(RSREG);
- desc.flags |= OPFLAG_READS_MEMORY | OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.set_r_used(RSREG);
+ desc.set_reads_memory();
+ desc.set_can_cause_exception();
return true;
case 0x3a: // SWC2
case 0x3e: // SDC2
- desc.regin[0] |= REGFLAG_R(RSREG);
- desc.flags |= OPFLAG_WRITES_MEMORY | OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.set_r_used(RSREG);
+ desc.set_writes_memory();
+ desc.set_can_cause_exception();
return true;
case 0x33: // PREF
@@ -234,7 +267,7 @@ bool mips3_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
// single instruction in the 'special' group
//-------------------------------------------------
-bool mips3_frontend::describe_special(uint32_t op, opcode_desc &desc)
+bool mips3_device::frontend::describe_special(uint32_t op, opcode_desc &desc)
{
switch (op & 63)
{
@@ -247,15 +280,15 @@ bool mips3_frontend::describe_special(uint32_t op, opcode_desc &desc)
case 0x3c: // DSLL32
case 0x3e: // DSRL32
case 0x3f: // DSRA32
- desc.regin[0] |= REGFLAG_R(RTREG);
- desc.regout[0] |= REGFLAG_R(RDREG);
+ desc.set_r_used(RTREG);
+ desc.set_r_modified(RDREG);
return true;
case 0x0a: // MOVZ - MIPS IV
case 0x0b: // MOVN - MIPS IV
if (m_mips3->m_flavor < mips3_device::MIPS3_TYPE_MIPS_IV)
return false;
- desc.regin[0] |= REGFLAG_R(RDREG);
+ desc.set_r_used(RDREG);
[[fallthrough]];
case 0x04: // SLLV
case 0x06: // SRLV
@@ -273,17 +306,19 @@ bool mips3_frontend::describe_special(uint32_t op, opcode_desc &desc)
case 0x2b: // SLTU
case 0x2d: // DADDU
case 0x2f: // DSUBU
- desc.regin[0] |= REGFLAG_R(RSREG) | REGFLAG_R(RTREG);
- desc.regout[0] |= REGFLAG_R(RDREG);
+ desc.set_r_used(RSREG);
+ desc.set_r_used(RTREG);
+ desc.set_r_modified(RDREG);
return true;
case 0x20: // ADD
case 0x22: // SUB
case 0x2c: // DADD
case 0x2e: // DSUB
- desc.regin[0] |= REGFLAG_R(RSREG) | REGFLAG_R(RTREG);
- desc.regout[0] |= REGFLAG_R(RDREG);
- desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.set_r_used(RSREG);
+ desc.set_r_used(RTREG);
+ desc.set_r_modified(RDREG);
+ desc.set_can_cause_exception();
return true;
case 0x30: // TGE
@@ -292,84 +327,96 @@ bool mips3_frontend::describe_special(uint32_t op, opcode_desc &desc)
case 0x33: // TLTU
case 0x34: // TEQ
case 0x36: // TNE
- desc.regin[0] |= REGFLAG_R(RSREG) | REGFLAG_R(RTREG);
- desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.set_r_used(RSREG);
+ desc.set_r_used(RTREG);
+ desc.set_can_cause_exception();
return true;
case 0x01: // MOVF - MIPS IV
if (m_mips3->m_flavor < mips3_device::MIPS3_TYPE_MIPS_IV)
return false;
- desc.regin[0] |= REGFLAG_R(RSREG);
- desc.regin[2] |= REGFLAG_FCC;
- desc.regout[0] |= REGFLAG_R(RDREG);
+ desc.set_r_used(RSREG);
+ desc.set_fcc_used();
+ desc.set_r_modified(RDREG);
return true;
case 0x08: // JR
- desc.regin[0] |= REGFLAG_R(RSREG);
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.set_r_used(RSREG);
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
desc.targetpc = BRANCH_TARGET_DYNAMIC;
desc.delayslots = 1;
return true;
case 0x09: // JALR
- desc.regin[0] |= REGFLAG_R(RSREG);
- desc.regout[0] |= REGFLAG_R(RDREG);
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.set_r_used(RSREG);
+ desc.set_r_modified(RDREG);
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
desc.targetpc = BRANCH_TARGET_DYNAMIC;
desc.delayslots = 1;
return true;
case 0x10: // MFHI
- desc.regin[2] |= REGFLAG_HI;
- desc.regout[0] |= REGFLAG_R(RDREG);
+ desc.set_hi_used();
+ desc.set_r_modified(RDREG);
return true;
case 0x11: // MTHI
- desc.regin[0] |= REGFLAG_R(RSREG);
- desc.regout[2] |= REGFLAG_HI;
+ desc.set_r_used(RSREG);
+ desc.set_hi_modified();
return true;
case 0x12: // MFLO
- desc.regin[2] |= REGFLAG_LO;
- desc.regout[0] |= REGFLAG_R(RDREG);
+ desc.set_lo_used();
+ desc.set_r_modified(RDREG);
return true;
case 0x13: // MTLO
- desc.regin[0] |= REGFLAG_R(RSREG);
- desc.regout[2] |= REGFLAG_LO;
+ desc.set_r_used(RSREG);
+ desc.set_lo_modified();
return true;
case 0x18: // MULT
case 0x19: // MULTU
- desc.regin[0] |= REGFLAG_R(RSREG) | REGFLAG_R(RTREG);
- desc.regout[2] |= REGFLAG_LO | REGFLAG_HI;
+ desc.set_r_used(RSREG);
+ desc.set_r_used(RTREG);
+ desc.set_lo_modified();
+ desc.set_hi_modified();
desc.cycles = 3;
return true;
case 0x1a: // DIV
case 0x1b: // DIVU
- desc.regin[0] |= REGFLAG_R(RSREG) | REGFLAG_R(RTREG);
- desc.regout[2] |= REGFLAG_LO | REGFLAG_HI;
+ desc.set_r_used(RSREG);
+ desc.set_r_used(RTREG);
+ desc.set_lo_modified();
+ desc.set_hi_modified();
desc.cycles = 35;
return true;
case 0x1c: // DMULT
case 0x1d: // DMULTU
- desc.regin[0] |= REGFLAG_R(RSREG) | REGFLAG_R(RTREG);
- desc.regout[2] |= REGFLAG_LO | REGFLAG_HI;
+ desc.set_r_used(RSREG);
+ desc.set_r_used(RTREG);
+ desc.set_lo_modified();
+ desc.set_hi_modified();
desc.cycles = 7;
return true;
case 0x1e: // DDIV
case 0x1f: // DDIVU
- desc.regin[0] |= REGFLAG_R(RSREG) | REGFLAG_R(RTREG);
- desc.regout[2] |= REGFLAG_LO | REGFLAG_HI;
+ desc.set_r_used(RSREG);
+ desc.set_r_used(RTREG);
+ desc.set_lo_modified();
+ desc.set_hi_modified();
desc.cycles = 67;
return true;
case 0x0c: // SYSCALL
case 0x0d: // BREAK
- desc.flags |= OPFLAG_WILL_CAUSE_EXCEPTION | OPFLAG_END_SEQUENCE;
+ desc.set_will_cause_exception();
+ desc.set_end_sequence();
return true;
case 0x0f: // SYNC
@@ -386,7 +433,7 @@ bool mips3_frontend::describe_special(uint32_t op, opcode_desc &desc)
// single instruction in the 'regimm' group
//-------------------------------------------------
-bool mips3_frontend::describe_regimm(uint32_t op, opcode_desc &desc)
+bool mips3_device::frontend::describe_regimm(uint32_t op, opcode_desc &desc)
{
switch (RTREG)
{
@@ -395,11 +442,14 @@ bool mips3_frontend::describe_regimm(uint32_t op, opcode_desc &desc)
case 0x02: // BLTZL
case 0x03: // BGEZL
if (RTREG == 0x01 && RSREG == 0)
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ {
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
+ }
else
{
- desc.regin[0] |= REGFLAG_R(RSREG);
- desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+ desc.set_r_used(RSREG);
+ desc.set_is_conditional_branch();
}
desc.targetpc = desc.pc + 4 + SIMMVAL * 4;
desc.delayslots = 1;
@@ -412,8 +462,8 @@ bool mips3_frontend::describe_regimm(uint32_t op, opcode_desc &desc)
case 0x0b: // TLTIU
case 0x0c: // TEQI
case 0x0e: // TNEI
- desc.regin[0] |= REGFLAG_R(RSREG);
- desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.set_r_used(RSREG);
+ desc.set_can_cause_exception();
return true;
case 0x10: // BLTZAL
@@ -421,13 +471,16 @@ bool mips3_frontend::describe_regimm(uint32_t op, opcode_desc &desc)
case 0x12: // BLTZALL
case 0x13: // BGEZALL
if (RTREG == 0x11 && RSREG == 0)
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ {
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
+ }
else
{
- desc.regin[0] |= REGFLAG_R(RSREG);
- desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+ desc.set_r_used(RSREG);
+ desc.set_is_conditional_branch();
}
- desc.regout[0] |= REGFLAG_R(31);
+ desc.set_r_modified(31);
desc.targetpc = desc.pc + 4 + SIMMVAL * 4;
desc.delayslots = 1;
desc.skipslots = (RTREG & 0x02) ? 1 : 0;
@@ -443,7 +496,7 @@ bool mips3_frontend::describe_regimm(uint32_t op, opcode_desc &desc)
// instruction in the IDT-specific group
//-------------------------------------------------
-bool mips3_frontend::describe_idt(uint32_t op, opcode_desc &desc)
+bool mips3_device::frontend::describe_idt(uint32_t op, opcode_desc &desc)
{
// only on the R4650
if (m_mips3->m_flavor != mips3_device::MIPS3_TYPE_R4650)
@@ -453,14 +506,18 @@ bool mips3_frontend::describe_idt(uint32_t op, opcode_desc &desc)
{
case 0: // MAD
case 1: // MADU
- desc.regin[0] |= REGFLAG_R(RSREG) | REGFLAG_R(RTREG);
- desc.regin[2] |= REGFLAG_LO | REGFLAG_HI;
- desc.regout[2] |= REGFLAG_LO | REGFLAG_HI;
+ desc.set_r_used(RSREG);
+ desc.set_r_used(RTREG);
+ desc.set_lo_used();
+ desc.set_hi_used();
+ desc.set_lo_modified();
+ desc.set_hi_modified();
return true;
case 2: // MUL
- desc.regin[0] |= REGFLAG_R(RSREG) | REGFLAG_R(RTREG);
- desc.regout[0] |= REGFLAG_R(RDREG);
+ desc.set_r_used(RSREG);
+ desc.set_r_used(RTREG);
+ desc.set_r_modified(RDREG);
desc.cycles = 3;
return true;
}
@@ -474,10 +531,10 @@ bool mips3_frontend::describe_idt(uint32_t op, opcode_desc &desc)
// single instruction in the COP0 group
//-------------------------------------------------
-bool mips3_frontend::describe_cop0(uint32_t op, opcode_desc &desc)
+bool mips3_device::frontend::describe_cop0(uint32_t op, opcode_desc &desc)
{
// any COP0 instruction can potentially cause an exception
- desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.set_can_cause_exception();
switch (RSREG)
{
@@ -487,23 +544,27 @@ bool mips3_frontend::describe_cop0(uint32_t op, opcode_desc &desc)
desc.cycles += MIPS3_COUNT_READ_CYCLES;
if (RDREG == COP0_Cause)
desc.cycles += MIPS3_CAUSE_READ_CYCLES;
- desc.regout[0] |= REGFLAG_R(RTREG);
+ desc.set_r_modified(RTREG);
return true;
case 0x02: // CFCz
- desc.regout[0] |= REGFLAG_R(RTREG);
+ desc.set_r_modified(RTREG);
return true;
case 0x04: // MTCz
case 0x05: // DMTCz
case 0x06: // CTCz
- desc.regin[0] |= REGFLAG_R(RTREG);
+ desc.set_r_used(RTREG);
if (RSREG == 0x04 || RSREG == 0x05)
{
if (RDREG == COP0_Cause)
- desc.flags |= OPFLAG_CAN_TRIGGER_SW_INT;
+ desc.set_can_trigger_sw_int();
if (RDREG == COP0_Status)
- desc.flags |= OPFLAG_CAN_EXPOSE_EXTERNAL_INT | OPFLAG_CAN_CHANGE_MODES | OPFLAG_END_SEQUENCE;
+ {
+ desc.set_can_expose_external_int();
+ desc.set_can_change_modes();
+ desc.set_end_sequence();
+ }
}
return true;
@@ -512,7 +573,7 @@ bool mips3_frontend::describe_cop0(uint32_t op, opcode_desc &desc)
{
case 0x00: // BCzF
case 0x01: // BCzT
- desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+ desc.set_is_conditional_branch();
desc.targetpc = desc.pc + 4 + SIMMVAL * 4;
desc.delayslots = 1;
return true;
@@ -530,11 +591,13 @@ bool mips3_frontend::describe_cop0(uint32_t op, opcode_desc &desc)
case 0x02: // TLBWI
case 0x06: // TLBWR
- desc.flags |= OPFLAG_MODIFIES_TRANSLATION;
+ desc.set_modifies_translation();
return true;
case 0x18: // ERET
- desc.flags |= OPFLAG_CAN_CHANGE_MODES | OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
+ desc.set_can_change_modes();
return true;
}
return false;
@@ -549,31 +612,31 @@ bool mips3_frontend::describe_cop0(uint32_t op, opcode_desc &desc)
// single instruction in the COP1 group
//-------------------------------------------------
-bool mips3_frontend::describe_cop1(uint32_t op, opcode_desc &desc)
+bool mips3_device::frontend::describe_cop1(uint32_t op, opcode_desc &desc)
{
// any COP1 instruction can potentially cause an exception
-// desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
+ //desc.set_can_cause_exception();
switch (RSREG)
{
case 0x00: // MFCz
case 0x01: // DMFCz
- desc.regin[1] |= REGFLAG_CPR1(RDREG);
- desc.regout[0] |= REGFLAG_R(RTREG);
+ desc.set_cpr1_used(RDREG);
+ desc.set_r_modified(RTREG);
return true;
case 0x02: // CFCz
- desc.regout[0] |= REGFLAG_R(RTREG);
+ desc.set_r_modified(RTREG);
return true;
case 0x04: // MTCz
case 0x05: // DMTCz
- desc.regin[0] |= REGFLAG_R(RTREG);
- desc.regout[1] |= REGFLAG_CPR1(RDREG);
+ desc.set_r_used(RTREG);
+ desc.set_cpr1_modified(RDREG);
return true;
case 0x06: // CTCz
- desc.regin[0] |= REGFLAG_R(RTREG);
+ desc.set_r_used(RTREG);
return true;
case 0x08: // BC
@@ -583,8 +646,8 @@ bool mips3_frontend::describe_cop1(uint32_t op, opcode_desc &desc)
case 0x01: // BCzT
case 0x02: // BCzFL
case 0x03: // BCzTL
- desc.regin[2] |= REGFLAG_FCC;
- desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+ desc.set_fcc_used();
+ desc.set_is_conditional_branch();
desc.targetpc = desc.pc + 4 + SIMMVAL * 4;
desc.delayslots = 1;
desc.skipslots = (RTREG & 0x02) ? 1 : 0;
@@ -605,8 +668,9 @@ bool mips3_frontend::describe_cop1(uint32_t op, opcode_desc &desc)
case 0x01: // SUB
case 0x02: // MUL
case 0x03: // DIV
- desc.regin[1] |= REGFLAG_CPR1(FSREG) | REGFLAG_CPR1(FTREG);
- desc.regout[1] |= REGFLAG_CPR1(FDREG);
+ desc.set_cpr1_used(FSREG);
+ desc.set_cpr1_used(FTREG);
+ desc.set_cpr1_modified(FDREG);
return true;
case 0x15: // RECIP - MIPS IV
@@ -630,21 +694,21 @@ bool mips3_frontend::describe_cop1(uint32_t op, opcode_desc &desc)
case 0x21: // CVT.D
case 0x24: // CVT.W
case 0x25: // CVT.L
- desc.regin[1] |= REGFLAG_CPR1(FSREG);
- desc.regout[1] |= REGFLAG_CPR1(FDREG);
+ desc.set_cpr1_used(FSREG);
+ desc.set_cpr1_modified(FDREG);
return true;
case 0x11: // MOVT/F - MIPS IV
if (m_mips3->m_flavor < mips3_device::MIPS3_TYPE_MIPS_IV)
return false;
- desc.regin[1] |= REGFLAG_CPR1(FSREG);
- desc.regin[2] |= REGFLAG_FCC;
- desc.regout[1] |= REGFLAG_CPR1(FDREG);
+ desc.set_cpr1_used(FSREG);
+ desc.set_fcc_used();
+ desc.set_cpr1_modified(FDREG);
return true;
case 0x30: case 0x38: // C.F
case 0x31: case 0x39: // C.UN
- desc.regout[2] |= REGFLAG_FCC;
+ desc.set_fcc_modified();
return true;
case 0x32: case 0x3a: // C.EQ
@@ -653,8 +717,9 @@ bool mips3_frontend::describe_cop1(uint32_t op, opcode_desc &desc)
case 0x35: case 0x3d: // C.ULT
case 0x36: case 0x3e: // C.OLE
case 0x37: case 0x3f: // C.ULE
- desc.regin[1] |= REGFLAG_CPR1(FSREG) | REGFLAG_CPR1(FTREG);
- desc.regout[2] |= REGFLAG_FCC;
+ desc.set_cpr1_used(FSREG);
+ desc.set_cpr1_used(FTREG);
+ desc.set_fcc_modified();
return true;
}
return false;
@@ -669,7 +734,7 @@ bool mips3_frontend::describe_cop1(uint32_t op, opcode_desc &desc)
// single instruction in the COP1X group
//-------------------------------------------------
-bool mips3_frontend::describe_cop1x(uint32_t op, opcode_desc &desc)
+bool mips3_device::frontend::describe_cop1x(uint32_t op, opcode_desc &desc)
{
// any COP1 instruction can potentially cause an exception
// desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
@@ -678,16 +743,18 @@ bool mips3_frontend::describe_cop1x(uint32_t op, opcode_desc &desc)
{
case 0x00: // LWXC1
case 0x01: // LDXC1
- desc.regin[0] |= REGFLAG_R(RSREG) | REGFLAG_R(RTREG);
- desc.regout[1] |= REGFLAG_CPR1(FDREG);
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_r_used(RSREG);
+ desc.set_r_used(RTREG);
+ desc.set_cpr1_modified(FDREG);
+ desc.set_reads_memory();
return true;
case 0x08: // SWXC1
case 0x09: // SDXC1
- desc.regin[0] |= REGFLAG_R(RSREG) | REGFLAG_R(RTREG);
- desc.regin[1] |= REGFLAG_CPR1(FDREG);
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_r_used(RSREG);
+ desc.set_r_used(RTREG);
+ desc.set_cpr1_used(FDREG);
+ desc.set_writes_memory();
return true;
case 0x0f: // PREFX
@@ -698,8 +765,10 @@ bool mips3_frontend::describe_cop1x(uint32_t op, opcode_desc &desc)
case 0x28: case 0x29: // MSUB
case 0x30: case 0x31: // NMADD
case 0x38: case 0x39: // NMSUB
- desc.regin[1] |= REGFLAG_CPR1(FSREG) | REGFLAG_CPR1(FTREG) | REGFLAG_CPR1(FRREG);
- desc.regout[1] |= REGFLAG_CPR1(FDREG);
+ desc.set_cpr1_used(FSREG);
+ desc.set_cpr1_used(FTREG);
+ desc.set_cpr1_used(FRREG);
+ desc.set_cpr1_modified(FDREG);
return true;
}
@@ -712,23 +781,23 @@ bool mips3_frontend::describe_cop1x(uint32_t op, opcode_desc &desc)
// single instruction in the COP2 group
//-------------------------------------------------
-bool mips3_frontend::describe_cop2(uint32_t op, opcode_desc &desc)
+bool mips3_device::frontend::describe_cop2(uint32_t op, opcode_desc &desc)
{
// any COP2 instruction can potentially cause an exception
- desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.set_can_cause_exception();
switch (RSREG)
{
case 0x00: // MFCz
case 0x01: // DMFCz
case 0x02: // CFCz
- desc.regout[0] |= REGFLAG_R(RTREG);
+ desc.set_r_modified(RTREG);
return true;
case 0x04: // MTCz
case 0x05: // DMTCz
case 0x06: // CTCz
- desc.regin[0] |= REGFLAG_R(RTREG);
+ desc.set_r_used(RTREG);
return true;
case 0x08: // BC
@@ -736,7 +805,7 @@ bool mips3_frontend::describe_cop2(uint32_t op, opcode_desc &desc)
{
case 0x00: // BCzF
case 0x01: // BCzT
- desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+ desc.set_is_conditional_branch();
desc.targetpc = desc.pc + 4 + SIMMVAL * 4;
desc.delayslots = 1;
return true;
diff --git a/src/devices/cpu/mips/mips3fe.h b/src/devices/cpu/mips/mips3fe.h
index 0b8e9d79fec..322c007417a 100644
--- a/src/devices/cpu/mips/mips3fe.h
+++ b/src/devices/cpu/mips/mips3fe.h
@@ -12,21 +12,121 @@
#pragma once
+#include "mips3.h"
+
+#include "cpu/drcfe.h"
+
+#include <cassert>
+#include <bitset>
+
//**************************************************************************
-// MACROS
+// STRUCTURES
//**************************************************************************
-// register flags 0
-#define REGFLAG_R(n) (((n) == 0) ? 0 : (1 << (n)))
+class mips3_device::opcode_desc : public opcode_desc_base<opcode_desc, 68>
+{
+public:
+ enum
+ {
+ REG_FLAG_R0 = 0,
+ REG_FLAG_CPR10 = REG_FLAG_R0 + 32,
+ REG_FLAG_LO = REG_FLAG_CPR10 + 32,
+ REG_FLAG_HI,
+ REG_FLAG_FCC,
+
+ REG_FLAG_COUNT
+ };
+
+ offs_t physpc; // physical PC of this opcode
+
+ uint32_t opptr; // copy of opcode
+
+ uint32_t cycles; // number of cycles needed to execute
+
+ void set_r_used(unsigned n) { if (n) regin.set(REG_FLAG_R0 + n); }
+ void set_r_modified(unsigned n) { if (n) regout.set(REG_FLAG_R0 + n); }
+ void set_cpr1_used(unsigned n) { regin.set(REG_FLAG_CPR10 + n); }
+ void set_cpr1_modified(unsigned n) { regout.set(REG_FLAG_CPR10 + n); }
+ void set_lo_used() { regin.set(REG_FLAG_LO); }
+ void set_lo_modified() { regout.set(REG_FLAG_LO); }
+ void set_hi_used() { regin.set(REG_FLAG_HI); }
+ void set_hi_modified() { regout.set(REG_FLAG_HI); }
+ void set_fcc_used() { regin.set(REG_FLAG_FCC); }
+ void set_fcc_modified() { regout.set(REG_FLAG_FCC); }
+
+ void set_can_trigger_sw_int() { m_extra_flags.set(CAN_TRIGGER_SW_INT); }
+ void set_can_expose_external_int() { m_extra_flags.set(CAN_EXPOSE_EXTERNAL_INT); }
+ void set_modifies_translation() { m_extra_flags.set(MODIFIES_TRANSLATION); }
+ void set_compiler_unmapped() { m_extra_flags.set(COMPILER_UNMAPPED); }
+ void set_can_change_modes() { m_extra_flags.set(CAN_CHANGE_MODES); }
+ void set_reads_memory() { m_extra_flags.set(READS_MEMORY); }
+ void set_writes_memory() { m_extra_flags.set(WRITES_MEMORY); }
+
+ bool can_trigger_sw_int() { return m_extra_flags[CAN_TRIGGER_SW_INT]; }
+ bool can_expose_external_int() { return m_extra_flags[CAN_EXPOSE_EXTERNAL_INT]; }
+ bool modifies_translation() const { return m_extra_flags[MODIFIES_TRANSLATION]; }
+ bool compiler_unmapped() const { return m_extra_flags[COMPILER_UNMAPPED]; }
+ bool can_change_modes() const { return m_extra_flags[CAN_CHANGE_MODES]; }
+ bool reads_memory() const { return m_extra_flags[READS_MEMORY]; }
+ bool writes_memory() const { return m_extra_flags[WRITES_MEMORY]; }
+
+ // compute the exception PC
+ uint32_t epc() const { return in_delay_slot() ? (pc - 3) : pc; }
+
+ void reset(offs_t curpc, bool in_delay_slot)
+ {
+ static_assert(REG_FLAG_COUNT <= 68);
+
+ opcode_desc_base::reset(curpc, in_delay_slot);
+
+ physpc = curpc;
+ opptr = 0;
+ cycles = 0;
+ m_extra_flags.reset();
+ }
+
+private:
+ enum
+ {
+ CAN_TRIGGER_SW_INT = 0,
+ CAN_EXPOSE_EXTERNAL_INT,
+ MODIFIES_TRANSLATION,
+ COMPILER_UNMAPPED,
+ CAN_CHANGE_MODES,
+ READS_MEMORY,
+ WRITES_MEMORY,
+
+ EXTRA_FLAG_COUNT
+ };
+
+ std::bitset<EXTRA_FLAG_COUNT> m_extra_flags;
+};
+
+
+class mips3_device::frontend : public drc_frontend_base<opcode_desc>
+{
+public:
+ // construction/destruction
+ frontend(mips3_device *mips3, uint32_t window_start, uint32_t window_end, uint32_t max_sequence);
+ ~frontend();
+
+ opcode_desc const *describe_code(offs_t startpc);
-// register flags 1
-#define REGFLAG_CPR1(n) (1 << (n))
+private:
+ bool describe(opcode_desc &desc, opcode_desc const *prev);
-// register flags 2
-#define REGFLAG_LO (1 << 0)
-#define REGFLAG_HI (1 << 1)
-#define REGFLAG_FCC (1 << 2)
+ // internal helpers
+ bool describe_special(uint32_t op, opcode_desc &desc);
+ bool describe_regimm(uint32_t op, opcode_desc &desc);
+ bool describe_idt(uint32_t op, opcode_desc &desc);
+ bool describe_cop0(uint32_t op, opcode_desc &desc);
+ bool describe_cop1(uint32_t op, opcode_desc &desc);
+ bool describe_cop1x(uint32_t op, opcode_desc &desc);
+ bool describe_cop2(uint32_t op, opcode_desc &desc);
+ // internal state
+ mips3_device *m_mips3;
+};
#endif // MAME_CPU_MIPS_MIPS3FE_H
diff --git a/src/devices/cpu/powerpc/ppc.h b/src/devices/cpu/powerpc/ppc.h
index 08aedd46741..d00bcac10a1 100644
--- a/src/devices/cpu/powerpc/ppc.h
+++ b/src/devices/cpu/powerpc/ppc.h
@@ -15,13 +15,13 @@
#include "ppc_dasm.h"
-#include "cpu/drcfe.h"
#include "cpu/drcuml.h"
#include "cpu/drcumlsh.h"
#include "divtlb.h"
#include <algorithm>
+#include <bitset>
/***************************************************************************
@@ -180,6 +180,7 @@ class ppc_device : public cpu_device, public device_vtlb_interface
{
protected:
class frontend;
+ class opcode_desc;
/* PowerPC flavors */
enum powerpc_flavor
@@ -699,8 +700,8 @@ protected:
bool generate_instruction_3b(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc);
bool generate_instruction_3f(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc);
void log_add_disasm_comment(drcuml_block &block, uint32_t pc, uint32_t op);
- const char *log_desc_flags_to_string(uint32_t flags);
- void log_register_list(const char *string, const uint32_t *reglist, const uint32_t *regnostarlist);
+ const char *log_desc_flags_to_string(const opcode_desc &desc);
+ void log_register_list(const char *string, const std::bitset<128> &reglist, const std::bitset<128> *regnostarlist);
void log_opcode_desc(const opcode_desc *desclist, int indent);
private:
diff --git a/src/devices/cpu/powerpc/ppcdrc.cpp b/src/devices/cpu/powerpc/ppcdrc.cpp
index 38eaa3a6908..ecb4fe09024 100644
--- a/src/devices/cpu/powerpc/ppcdrc.cpp
+++ b/src/devices/cpu/powerpc/ppcdrc.cpp
@@ -16,10 +16,10 @@
#include "emu.h"
#include "ppc.h"
+
#include "ppccom.h"
#include "ppcfe.h"
-#include "cpu/drcfe.h"
#include "cpu/drcuml.h"
#include "cpu/drcumlsh.h"
@@ -348,9 +348,11 @@ void ppc_device::code_compile_block(uint8_t mode, offs_t pc)
block.append_comment("-------------------------"); // comment
/* determine the last instruction in this sequence */
- for (seqlast = seqhead; seqlast != nullptr; seqlast = seqlast->next())
- if (seqlast->flags & OPFLAG_END_SEQUENCE)
+ for (seqlast = seqhead; seqlast; seqlast = seqlast->next())
+ {
+ if (seqlast->end_sequence())
break;
+ }
assert(seqlast != nullptr);
/* if we don't have a hash for this mode/pc, or if we are overriding all, add one */
@@ -379,7 +381,7 @@ void ppc_device::code_compile_block(uint8_t mode, offs_t pc)
generate_checksum_block(block, &compiler, seqhead, seqlast); // <checksum>
/* label this instruction, if it may be jumped to locally */
- if (seqhead->flags & OPFLAG_IS_BRANCH_TARGET)
+ if (seqhead->is_branch_target())
UML_LABEL(block, seqhead->pc | 0x80000000); // label seqhead->pc | 0x80000000
/* iterate over instructions in the sequence and compile them */
@@ -387,7 +389,7 @@ void ppc_device::code_compile_block(uint8_t mode, offs_t pc)
generate_sequence_instruction(block, &compiler, curdesc); // <instruction>
/* if we need to return to the start, do it */
- if (seqlast->flags & OPFLAG_RETURN_TO_START)
+ if (seqlast->return_to_start())
nextpc = pc;
/* otherwise we just go to the next instruction */
@@ -398,7 +400,7 @@ void ppc_device::code_compile_block(uint8_t mode, offs_t pc)
generate_update_cycles(block, &compiler, nextpc, true); // <subtract cycles>
/* if the last instruction can change modes, use a variable mode; otherwise, assume the same mode */
- if (seqlast->flags & OPFLAG_CAN_CHANGE_MODES)
+ if (seqlast->can_change_modes())
UML_HASHJMP(block, mem(&m_core->mode), nextpc, *m_nocode);// hashjmp <mode>,nextpc,nocode
else if (seqlast->next() == nullptr || seqlast->next()->pc != nextpc)
UML_HASHJMP(block, m_core->mode, nextpc, *m_nocode);// hashjmp <mode>,nextpc,nocode
@@ -1573,11 +1575,11 @@ void ppc_device::generate_checksum_block(drcuml_block &block, compiler_state *co
/* loose verify or single instruction: just compare and fail */
if (!(m_drcoptions & PPCDRC_STRICT_VERIFY) || seqhead->next() == nullptr)
{
- if (!(seqhead->flags & OPFLAG_VIRTUAL_NOOP))
+ if (!seqhead->virtual_noop())
{
const void *base = m_prptr(seqhead->physpc);
UML_LOAD(block, I0, base, 0, SIZE_DWORD, SCALE_x4); // load i0,base,dword
- UML_CMP(block, I0, seqhead->opptr.l[0]); // cmp i0,*opptr
+ UML_CMP(block, I0, seqhead->opptr); // cmp i0,*opptr
UML_EXHc(block, COND_NE, *m_nocode, seqhead->pc); // exne nocode,seqhead->pc
}
}
@@ -1587,28 +1589,32 @@ void ppc_device::generate_checksum_block(drcuml_block &block, compiler_state *co
{
#if 0
for (curdesc = seqhead->next(); curdesc != seqlast->next(); curdesc = curdesc->next())
- if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP))
+ {
+ if (!curdesc->virtual_noop())
{
const void *base = m_prptr(seqhead->physpc);
- UML_LOAD(block, I0, base, 0, SIZE_DWORD, SCALE_x4); // load i0,base,dword
- UML_CMP(block, I0, curdesc->opptr.l[0]); // cmp i0,*opptr
- UML_EXHc(block, COND_NE, *m_nocode, seqhead->pc); // exne nocode,seqhead->pc
+ UML_LOAD(block, I0, base, 0, SIZE_DWORD, SCALE_x4);
+ UML_CMP(block, I0, curdesc->opptr);
+ UML_EXHc(block, COND_NE, *m_nocode, seqhead->pc);
}
+ }
#else
uint32_t sum = 0;
const void *base = m_prptr(seqhead->physpc);
- UML_LOAD(block, I0, base, 0, SIZE_DWORD, SCALE_x4); // load i0,base,dword
- sum += seqhead->opptr.l[0];
+ UML_LOAD(block, I0, base, 0, SIZE_DWORD, SCALE_x4);
+ sum += seqhead->opptr;
for (curdesc = seqhead->next(); curdesc != seqlast->next(); curdesc = curdesc->next())
- if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP))
+ {
+ if (!curdesc->virtual_noop())
{
base = m_prptr(curdesc->physpc);
- UML_LOAD(block, I1, base, 0, SIZE_DWORD, SCALE_x4); // load i1,base,dword
- UML_ADD(block, I0, I0, I1); // add i0,i0,i1
- sum += curdesc->opptr.l[0];
+ UML_LOAD(block, I1, base, 0, SIZE_DWORD, SCALE_x4);
+ UML_ADD(block, I0, I0, I1);
+ sum += curdesc->opptr;
}
- UML_CMP(block, I0, sum); // cmp i0,sum
- UML_EXHc(block, COND_NE, *m_nocode, seqhead->pc); // exne nocode,seqhead->pc
+ }
+ UML_CMP(block, I0, sum);
+ UML_EXHc(block, COND_NE, *m_nocode, seqhead->pc);
#endif
}
}
@@ -1624,8 +1630,8 @@ void ppc_device::generate_sequence_instruction(drcuml_block &block, compiler_sta
int hotnum;
/* add an entry for the log */
- if (m_drcuml->logging() && !(desc->flags & OPFLAG_VIRTUAL_NOOP))
- log_add_disasm_comment(block, desc->pc, desc->opptr.l[0]);
+ if (m_drcuml->logging() && !desc->virtual_noop())
+ 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
@@ -1635,7 +1641,7 @@ void ppc_device::generate_sequence_instruction(drcuml_block &block, compiler_sta
/* is this a hotspot? */
for (hotnum = 0; hotnum < PPC_MAX_HOTSPOTS; hotnum++)
- if (m_hotspot[hotnum].pc != 0 && desc->pc == m_hotspot[hotnum].pc && desc->opptr.l[0] == m_hotspot[hotnum].opcode)
+ if (m_hotspot[hotnum].pc != 0 && desc->pc == m_hotspot[hotnum].pc && desc->opptr == m_hotspot[hotnum].opcode)
{
compiler->cycles += m_hotspot[hotnum].cycles;
break;
@@ -1661,7 +1667,7 @@ void ppc_device::generate_sequence_instruction(drcuml_block &block, compiler_sta
}
/* if we hit an unmapped address, fatal error */
- if (desc->flags & OPFLAG_COMPILER_UNMAPPED)
+ if (desc->compiler_unmapped())
{
UML_MOV(block, mem(&m_core->pc), desc->pc); // mov [pc],desc->pc
save_fast_iregs(block); // <save fastregs>
@@ -1670,7 +1676,7 @@ void ppc_device::generate_sequence_instruction(drcuml_block &block, compiler_sta
}
/* if we hit a compiler page fault, it's just like a TLB mismatch */
- if (desc->flags & OPFLAG_COMPILER_PAGE_FAULT)
+ if (desc->compiler_page_fault())
{
if (PRINTF_MMU)
{
@@ -1687,7 +1693,7 @@ void ppc_device::generate_sequence_instruction(drcuml_block &block, compiler_sta
// validate our TLB entry at this PC; if we fail, we need to handle it
// TODO: this code is highly sus based on the PPC architecture manual, but I'll only disable for 601 for now
- if ((desc->flags & OPFLAG_VALIDATE_TLB) && (m_core->mode & MODE_DATA_TRANSLATION) && !(m_cap & PPCCAP_601BAT))
+ if (desc->validate_tlb() && (m_core->mode & MODE_DATA_TRANSLATION) && !(m_cap & PPCCAP_601BAT))
{
const vtlb_entry *tlbtable = vtlb_table();
@@ -1725,23 +1731,25 @@ void ppc_device::generate_sequence_instruction(drcuml_block &block, compiler_sta
}
}
- /* if this is an invalid opcode, generate the exception now */
- if (desc->flags & OPFLAG_INVALID_OPCODE)
- UML_EXH(block, *m_exception[EXCEPTION_PROGRAM], 0x80000); // exh exception_program,0x80000
-
- /* if this is a privileged opcode in user mode, generate the exception */
- else if ((desc->flags & OPFLAG_PRIVILEGED) && (m_core->mode & MODE_USER))
+ if (desc->invalid_opcode())
+ {
+ // if this is an invalid opcode, generate the exception now
+ UML_EXH(block, *m_exception[EXCEPTION_PROGRAM], 0x80000);
+ }
+ else if (desc->privileged() && (m_core->mode & MODE_USER))
+ {
+ // if this is a privileged opcode in user mode, generate the exception
UML_EXH(block, *m_exception[EXCEPTION_PROGRAM], 0x40000); // exh exception_program,0x40000
-
- /* otherwise, unless this is a virtual no-op, it's a regular instruction */
- else if (!(desc->flags & OPFLAG_VIRTUAL_NOOP))
+ }
+ else if (!desc->virtual_noop())
{
- /* compile the instruction */
+ // otherwise, unless this is a virtual no-op, it's a regular instruction
+ // compile the instruction
if (!generate_opcode(block, compiler, desc))
{
- UML_MOV(block, mem(&m_core->pc), desc->pc); // mov [pc],desc->pc
- UML_MOV(block, mem(&m_core->arg0), desc->opptr.l[0]); // mov [arg0],*desc->opptr.l
- UML_CALLC(block, cfunc_unimplemented, this); // callc cfunc_unimplemented,ppc
+ UML_MOV(block, mem(&m_core->pc), desc->pc);
+ UML_MOV(block, mem(&m_core->arg0), desc->opptr);
+ UML_CALLC(block, cfunc_unimplemented, this);
}
}
}
@@ -1758,9 +1766,9 @@ void ppc_device::generate_compute_flags(drcuml_block &block, const opcode_desc *
/* modify inputs based on required flags */
if (!DISABLE_FLAG_OPTIMIZATIONS)
{
- if (!(desc->regreq[3] & frontend::REGFLAG_XER_CA))
+ if (!frontend::REGFLAG_XER_CA(desc->regreq))
xermask &= ~XER_CA;
- if (!(desc->regreq[2] & frontend::REGFLAG_CR(0)))
+ if (!frontend::REGFLAG_CR(desc->regreq, 0))
updatecr = 0;
}
xerflags = ((xermask & XER_OV) ? uml::FLAG_V : 0) | ((xermask & XER_CA) ? uml::FLAG_C : 0);
@@ -1845,11 +1853,11 @@ void ppc_device::generate_fp_flags(drcuml_block &block, const opcode_desc *desc,
/* for now, only handle the FPRF field */
if (updatefprf)
{
- int regnum = G_RD(desc->opptr.l[0]);
+ int regnum = G_RD(desc->opptr);
if (m_fdregmap[regnum].is_float_register())
UML_FDMOV(block, mem(&m_core->f[regnum]), freg(m_fdregmap[regnum].freg() - REG_F0));
- UML_MOV(block, mem(&m_core->param0), G_RD(desc->opptr.l[0]));
+ UML_MOV(block, mem(&m_core->param0), G_RD(desc->opptr));
UML_CALLC(block, (c_function)cfunc_ppccom_update_fprf, this);
}
}
@@ -1879,7 +1887,7 @@ void ppc_device::generate_branch(drcuml_block &block, compiler_state *compiler,
if (desc->targetpc != BRANCH_TARGET_DYNAMIC)
{
generate_update_cycles(block, &compiler_temp, desc->targetpc, true); // <subtract cycles>
- if (desc->flags & OPFLAG_INTRABLOCK_BRANCH)
+ if (desc->intrablock_branch())
UML_JMP(block, desc->targetpc | 0x80000000); // jmp desc->targetpc | 0x80000000
else
UML_HASHJMP(block, m_core->mode, desc->targetpc, *m_nocode);
@@ -1933,7 +1941,7 @@ void ppc_device::generate_branch_bo(drcuml_block &block, compiler_state *compile
bool ppc_device::generate_opcode(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc)
{
- uint32_t op = desc->opptr.l[0];
+ uint32_t op = desc->opptr;
uint32_t opswitch = op >> 26;
switch (opswitch)
@@ -2331,7 +2339,7 @@ bool ppc_device::generate_opcode(drcuml_block &block, compiler_state *compiler,
bool ppc_device::generate_instruction_13(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc)
{
- uint32_t op = desc->opptr.l[0];
+ uint32_t op = desc->opptr;
uint32_t opswitch = (op >> 1) & 0x3ff;
switch (opswitch)
@@ -2468,7 +2476,7 @@ bool ppc_device::generate_instruction_13(drcuml_block &block, compiler_state *co
bool ppc_device::generate_instruction_1f(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc)
{
- uint32_t op = desc->opptr.l[0];
+ uint32_t op = desc->opptr;
uint32_t opswitch = (op >> 1) & 0x3ff;
int item;
@@ -2963,7 +2971,7 @@ bool ppc_device::generate_instruction_1f(drcuml_block &block, compiler_state *co
UML_CMP(block, I2, 0x00000020); // cmp rb,0x20
UML_JMPc(block, COND_S, compiler->labelnum); // bs 1:
- if (DISABLE_FLAG_OPTIMIZATIONS || (desc->regreq[3] & frontend::REGFLAG_XER_CA))
+ if (DISABLE_FLAG_OPTIMIZATIONS || frontend::REGFLAG_XER_CA(desc->regreq))
{
// for shift amt > 32, carry flag is the sign bit of Rs and the sign bit fills all bit positions
UML_TEST(block, R32(G_RS(op)), 0x80000000);
@@ -2974,7 +2982,7 @@ bool ppc_device::generate_instruction_1f(drcuml_block &block, compiler_state *co
UML_JMP(block, compiler->labelnum+1); // bra 2:
UML_LABEL(block, compiler->labelnum++); // 1:
- if (DISABLE_FLAG_OPTIMIZATIONS || (desc->regreq[3] & frontend::REGFLAG_XER_CA))
+ if (DISABLE_FLAG_OPTIMIZATIONS || frontend::REGFLAG_XER_CA(desc->regreq))
{
UML_SHL(block, I1, 0xffffffff, I2); // shl i1,0xffffffff,i2
UML_XOR(block, I1, I1, ~0); // xor i1,i1,~0
@@ -2995,7 +3003,7 @@ bool ppc_device::generate_instruction_1f(drcuml_block &block, compiler_state *co
return true;
case 0x338: /* SRAWIx */
- if (DISABLE_FLAG_OPTIMIZATIONS || (desc->regreq[3] & frontend::REGFLAG_XER_CA))
+ if (DISABLE_FLAG_OPTIMIZATIONS || frontend::REGFLAG_XER_CA(desc->regreq))
{
UML_AND(block, I0, R32(G_RS(op)), ~(0xffffffff << (G_SH(op) & 31)));// and i0,rs,~(0xffffffff << (sh & 31))
UML_SAR(block, I1, R32(G_RS(op)), 31); // sar i1,rs,31
@@ -3618,7 +3626,7 @@ bool ppc_device::generate_instruction_1f(drcuml_block &block, compiler_state *co
bool ppc_device::generate_instruction_3b(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc)
{
- uint32_t op = desc->opptr.l[0];
+ uint32_t op = desc->opptr;
uint32_t opswitch = (op >> 1) & 0x1f;
switch (opswitch)
@@ -3726,7 +3734,7 @@ bool ppc_device::generate_instruction_3b(drcuml_block &block, compiler_state *co
bool ppc_device::generate_instruction_3f(drcuml_block &block, compiler_state *compiler, const opcode_desc *desc)
{
- uint32_t op = desc->opptr.l[0];
+ uint32_t op = desc->opptr;
uint32_t opswitch = (op >> 1) & 0x3ff;
if (opswitch & 0x10)
@@ -3916,52 +3924,49 @@ void ppc_device::log_add_disasm_comment(drcuml_block &block, uint32_t pc, uint32
flags
-------------------------------------------------*/
-const char *ppc_device::log_desc_flags_to_string(uint32_t flags)
+const char *ppc_device::log_desc_flags_to_string(const opcode_desc &desc)
{
static char tempbuf[30];
char *dest = tempbuf;
/* branches */
- if (flags & OPFLAG_IS_UNCONDITIONAL_BRANCH)
+ if (desc.is_unconditional_branch())
*dest++ = 'U';
- else if (flags & OPFLAG_IS_CONDITIONAL_BRANCH)
+ else if (desc.is_conditional_branch())
*dest++ = 'C';
else
*dest++ = '.';
/* intrablock branches */
- *dest++ = (flags & OPFLAG_INTRABLOCK_BRANCH) ? 'i' : '.';
+ *dest++ = desc.intrablock_branch() ? 'i' : '.';
/* branch targets */
- *dest++ = (flags & OPFLAG_IS_BRANCH_TARGET) ? 'B' : '.';
+ *dest++ = desc.is_branch_target() ? 'B' : '.';
/* delay slots */
- *dest++ = (flags & OPFLAG_IN_DELAY_SLOT) ? 'D' : '.';
+ *dest++ = desc.in_delay_slot() ? 'D' : '.';
/* exceptions */
- if (flags & OPFLAG_WILL_CAUSE_EXCEPTION)
+ if (desc.will_cause_exception())
*dest++ = 'E';
- else if (flags & OPFLAG_CAN_CAUSE_EXCEPTION)
+ else if (desc.can_cause_exception())
*dest++ = 'e';
else
*dest++ = '.';
/* read/write */
- if (flags & OPFLAG_READS_MEMORY)
+ if (desc.reads_memory())
*dest++ = 'R';
- else if (flags & OPFLAG_WRITES_MEMORY)
+ else if (desc.writes_memory())
*dest++ = 'W';
else
*dest++ = '.';
/* TLB validation */
- *dest++ = (flags & OPFLAG_VALIDATE_TLB) ? 'V' : '.';
-
- /* TLB modification */
- *dest++ = (flags & OPFLAG_MODIFIES_TRANSLATION) ? 'T' : '.';
+ *dest++ = desc.validate_tlb() ? 'V' : '.';
/* redispatch */
- *dest++ = (flags & OPFLAG_REDISPATCH) ? 'R' : '.';
+ *dest++ = desc.redispatch() ? 'R' : '.';
return tempbuf;
}
@@ -3970,7 +3975,7 @@ const char *ppc_device::log_desc_flags_to_string(uint32_t flags)
log_register_list - log a list of GPR registers
-------------------------------------------------*/
-void ppc_device::log_register_list(const char *string, const uint32_t *reglist, const uint32_t *regnostarlist)
+void ppc_device::log_register_list(const char *string, const std::bitset<128> &reglist, const std::bitset<128> *regnostarlist)
{
static const char *const crtext[4] = { "lt", "gt", "eq", "so" };
int count = 0;
@@ -3978,92 +3983,102 @@ void ppc_device::log_register_list(const char *string, const uint32_t *reglist,
int crnum;
/* skip if nothing */
- if (reglist[0] == 0 && reglist[1] == 0 && reglist[2] == 0 && reglist[3] == 0)
+ if (reglist.none())
return;
m_drcuml->log_printf("[%s:", string);
for (regnum = 0; regnum < 32; regnum++)
- if (reglist[0] & frontend::REGFLAG_R(regnum))
+ {
+ if (frontend::REGFLAG_R(reglist, regnum))
{
m_drcuml->log_printf("%sr%d", (count++ == 0) ? "" : ",", regnum);
- if (regnostarlist != nullptr && !(regnostarlist[0] & frontend::REGFLAG_R(regnum)))
+ if (regnostarlist && !frontend::REGFLAG_R(*regnostarlist, regnum))
m_drcuml->log_printf("*");
}
+ }
for (regnum = 0; regnum < 32; regnum++)
- if (reglist[1] & frontend::REGFLAG_FR(regnum))
+ {
+ if (frontend::REGFLAG_FR(reglist, regnum))
{
m_drcuml->log_printf("%sfr%d", (count++ == 0) ? "" : ",", regnum);
- if (regnostarlist != nullptr && !(regnostarlist[1] & frontend::REGFLAG_FR(regnum)))
+ if (regnostarlist && !frontend::REGFLAG_FR(*regnostarlist, regnum))
m_drcuml->log_printf("*");
}
+ }
for (regnum = 0; regnum < 8; regnum++)
- if (reglist[2] & frontend::REGFLAG_CR(regnum))
+ {
+ if (frontend::REGFLAG_CR(reglist, regnum))
{
- if ((reglist[2] & frontend::REGFLAG_CR(regnum)) == frontend::REGFLAG_CR(regnum) && (regnostarlist == nullptr || (regnostarlist[2] & frontend::REGFLAG_CR(regnum)) == frontend::REGFLAG_CR(regnum)))
+ if ((frontend::REGFLAG_CR(reglist, regnum) == 0x0f) && (!regnostarlist || (frontend::REGFLAG_CR(*regnostarlist, regnum) == 0x0f)))
{
m_drcuml->log_printf("%scr%d", (count++ == 0) ? "" : ",", regnum);
- if (regnostarlist != nullptr && !(regnostarlist[2] & frontend::REGFLAG_CR(regnum)))
+ if (regnostarlist && !frontend::REGFLAG_CR(*regnostarlist, regnum))
m_drcuml->log_printf("*");
}
else
{
for (crnum = 0; crnum < 4; crnum++)
- if (reglist[2] & frontend::REGFLAG_CR_BIT(regnum * 4 + crnum))
+ {
+ if (frontend::REGFLAG_CR_BIT(reglist, regnum * 4 + crnum))
{
m_drcuml->log_printf("%scr%d[%s]", (count++ == 0) ? "" : ",", regnum, crtext[crnum]);
- if (regnostarlist != nullptr && !(regnostarlist[2] & frontend::REGFLAG_CR_BIT(regnum * 4 + crnum)))
+ if (regnostarlist && !frontend::REGFLAG_CR_BIT(*regnostarlist, regnum * 4 + crnum))
m_drcuml->log_printf("*");
}
+ }
}
}
+ }
- if (reglist[3] & frontend::REGFLAG_XER_CA)
+ if (frontend::REGFLAG_XER_CA(reglist))
{
m_drcuml->log_printf("%sxer_ca", (count++ == 0) ? "" : ",");
- if (regnostarlist != nullptr && !(regnostarlist[3] & frontend::REGFLAG_XER_CA))
+ if (regnostarlist && !frontend::REGFLAG_XER_CA(*regnostarlist))
m_drcuml->log_printf("*");
}
- if (reglist[3] & frontend::REGFLAG_XER_OV)
+ if (frontend::REGFLAG_XER_OV(reglist))
{
m_drcuml->log_printf("%sxer_ov", (count++ == 0) ? "" : ",");
- if (regnostarlist != nullptr && !(regnostarlist[3] & frontend::REGFLAG_XER_OV))
+ if (regnostarlist && !frontend::REGFLAG_XER_OV(*regnostarlist))
m_drcuml->log_printf("*");
}
- if (reglist[3] & frontend::REGFLAG_XER_SO)
+ if (frontend::REGFLAG_XER_SO(reglist))
{
m_drcuml->log_printf("%sxer_so", (count++ == 0) ? "" : ",");
- if (regnostarlist != nullptr && !(regnostarlist[3] & frontend::REGFLAG_XER_SO))
+ if (regnostarlist && !frontend::REGFLAG_XER_SO(*regnostarlist))
m_drcuml->log_printf("*");
}
- if (reglist[3] & frontend::REGFLAG_XER_COUNT)
+ if (frontend::REGFLAG_XER_COUNT(reglist))
{
m_drcuml->log_printf("%sxer_count", (count++ == 0) ? "" : ",");
- if (regnostarlist != nullptr && !(regnostarlist[3] & frontend::REGFLAG_XER_COUNT))
+ if (regnostarlist && !frontend::REGFLAG_XER_COUNT(*regnostarlist))
m_drcuml->log_printf("*");
}
- if (reglist[3] & frontend::REGFLAG_CTR)
+ if (frontend::REGFLAG_CTR(reglist))
{
m_drcuml->log_printf("%sctr", (count++ == 0) ? "" : ",");
- if (regnostarlist != nullptr && !(regnostarlist[3] & frontend::REGFLAG_CTR))
+ if (regnostarlist && !frontend::REGFLAG_CTR(*regnostarlist))
m_drcuml->log_printf("*");
}
- if (reglist[3] & frontend::REGFLAG_LR)
+ if (frontend::REGFLAG_LR(reglist))
{
m_drcuml->log_printf("%slr", (count++ == 0) ? "" : ",");
- if (regnostarlist != nullptr && !(regnostarlist[3] & frontend::REGFLAG_LR))
+ if (regnostarlist && !frontend::REGFLAG_LR(*regnostarlist))
m_drcuml->log_printf("*");
}
for (regnum = 0; regnum < 8; regnum++)
- if (reglist[3] & frontend::REGFLAG_FPSCR(regnum))
+ {
+ if (frontend::REGFLAG_FPSCR(reglist, regnum))
{
m_drcuml->log_printf("%sfpscr%d", (count++ == 0) ? "" : ",", regnum);
- if (regnostarlist != nullptr && !(regnostarlist[3] & frontend::REGFLAG_FPSCR(regnum)))
+ if (regnostarlist && !frontend::REGFLAG_FPSCR(*regnostarlist, regnum))
m_drcuml->log_printf("*");
}
+ }
m_drcuml->log_printf("] ");
}
@@ -4090,20 +4105,20 @@ void ppc_device::log_opcode_desc(const opcode_desc *desclist, int indent)
/* disassemble the current instruction and output it to the log */
if (m_drcuml->logging() || m_drcuml->logging_native())
{
- if (desclist->flags & OPFLAG_VIRTUAL_NOOP)
+ if (desclist->virtual_noop())
buffer << "<virtual nop>";
else
- m_dasm.dasm_one(buffer, desclist->pc, desclist->opptr.l[0]);
+ m_dasm.dasm_one(buffer, desclist->pc, desclist->opptr);
}
else
buffer << "???";
buffer.put('\0');
- m_drcuml->log_printf("%08X [%08X] t:%08X f:%s: %-30s", desclist->pc, desclist->physpc, desclist->targetpc, log_desc_flags_to_string(desclist->flags), &buffer.vec()[0]);
+ m_drcuml->log_printf("%08X [%08X] t:%08X f:%s: %-30s", desclist->pc, desclist->physpc, desclist->targetpc, log_desc_flags_to_string(*desclist), &buffer.vec()[0]);
/* output register states */
log_register_list("use", desclist->regin, nullptr);
- log_register_list("mod", desclist->regout, desclist->regreq);
+ log_register_list("mod", desclist->regout, &desclist->regreq);
m_drcuml->log_printf("\n");
/* if we have a delay slot, output it recursively */
@@ -4111,7 +4126,7 @@ void ppc_device::log_opcode_desc(const opcode_desc *desclist, int indent)
log_opcode_desc(desclist->delay.first(), indent + 1);
/* at the end of a sequence add a dividing line */
- if (desclist->flags & OPFLAG_END_SEQUENCE)
+ if (desclist->end_sequence())
m_drcuml->log_printf("-----\n");
}
}
diff --git a/src/devices/cpu/powerpc/ppcfe.cpp b/src/devices/cpu/powerpc/ppcfe.cpp
index 1e8fb105ee1..1819d906ba7 100644
--- a/src/devices/cpu/powerpc/ppcfe.cpp
+++ b/src/devices/cpu/powerpc/ppcfe.cpp
@@ -10,41 +10,44 @@
#include "emu.h"
#include "ppcfe.h"
+
#include "ppccom.h"
+#include "cpu/drcfe.ipp"
+
//**************************************************************************
// MACROS
//**************************************************************************
-#define GPR_USED(desc, x) do { (desc).regin[0] |= REGFLAG_R(x); } while (0)
-#define GPR_USED_OR_ZERO(desc, x) do { (desc).regin[0] |= ((x) == 0 ? 0 : REGFLAG_R(x)); } while (0)
-#define GPR_MODIFIED(desc, x) do { (desc).regout[0] |= REGFLAG_R(x); } while (0)
+#define GPR_USED(desc, x) do { (desc).regin.set(REG_BIT_R0 + x); } while (0)
+#define GPR_USED_OR_ZERO(desc, x) do { if (x) GPR_USED((desc), x); } while (0)
+#define GPR_MODIFIED(desc, x) do { (desc).regout.set(REG_BIT_R0 + x); } while (0)
-#define FPR_USED(desc, x) do { (desc).regin[1] |= REGFLAG_FR(x); } while (0)
-#define FPR_MODIFIED(desc, x) do { (desc).regout[1] |= REGFLAG_FR(x); } while (0)
+#define FPR_USED(desc, x) do { (desc).regin.set(REG_BIT_FR0 + x); } while (0)
+#define FPR_MODIFIED(desc, x) do { (desc).regout.set(REG_BIT_FR0 + x); } while (0)
-#define CR_USED(desc, x) do { (desc).regin[2] |= REGFLAG_CR(x); } while (0)
-#define CR_BIT_USED(desc, x) do { (desc).regin[2] |= REGFLAG_CR_BIT(x); } while (0)
-#define CR_MODIFIED(desc, x) do { (desc).regout[2] |= REGFLAG_CR(x); } while (0)
-#define CR_BIT_MODIFIED(desc, x) do { (desc).regout[2] |= REGFLAG_CR_BIT(x); } while (0)
+#define CR_USED(desc, x) do { CR_BIT_USED((desc), (x * 4) + 0); CR_BIT_USED((desc), (x * 4) + 1); CR_BIT_USED((desc), (x * 4) + 2); CR_BIT_USED((desc), (x * 4) + 3); } while (0)
+#define CR_BIT_USED(desc, x) do { (desc).regin.set(64 + 31 - x); } while (0)
+#define CR_MODIFIED(desc, x) do { CR_BIT_MODIFIED((desc), (x * 4) + 0); CR_BIT_MODIFIED((desc), (x * 4) + 1); CR_BIT_MODIFIED((desc), (x * 4) + 2); CR_BIT_MODIFIED((desc), (x * 4) + 3); } while (0)
+#define CR_BIT_MODIFIED(desc, x) do { (desc).regout.set(64 + 31 - x); } while (0)
-#define XER_CA_USED(desc) do { (desc).regin[3] |= REGFLAG_XER_CA; } while (0)
-#define XER_OV_USED(desc) do { (desc).regin[3] |= REGFLAG_XER_OV; } while (0)
-#define XER_SO_USED(desc) do { (desc).regin[3] |= REGFLAG_XER_SO; } while (0)
-#define XER_COUNT_USED(desc) do { (desc).regin[3] |= REGFLAG_XER_COUNT; } while (0)
-#define XER_CA_MODIFIED(desc) do { (desc).regout[3] |= REGFLAG_XER_CA; } while (0)
-#define XER_OV_MODIFIED(desc) do { (desc).regout[3] |= REGFLAG_XER_OV; } while (0)
-#define XER_SO_MODIFIED(desc) do { (desc).regout[3] |= REGFLAG_XER_SO; } while (0)
-#define XER_COUNT_MODIFIED(desc) do { (desc).regout[3] |= REGFLAG_XER_COUNT; } while (0)
+#define XER_CA_USED(desc) do { (desc).regin.set(REG_BIT_XER_CA); } while (0)
+#define XER_OV_USED(desc) do { (desc).regin.set(REG_BIT_XER_OV); } while (0)
+#define XER_SO_USED(desc) do { (desc).regin.set(REG_BIT_XER_SO); } while (0)
+#define XER_COUNT_USED(desc) do { (desc).regin.set(REG_BIT_XER_COUNT); } while (0)
+#define XER_CA_MODIFIED(desc) do { (desc).regout.set(REG_BIT_XER_CA); } while (0)
+#define XER_OV_MODIFIED(desc) do { (desc).regout.set(REG_BIT_XER_OV); } while (0)
+#define XER_SO_MODIFIED(desc) do { (desc).regout.set(REG_BIT_XER_SO); } while (0)
+#define XER_COUNT_MODIFIED(desc) do { (desc).regout.set(REG_BIT_XER_COUNT); } while (0)
-#define CTR_USED(desc) do { (desc).regin[3] |= REGFLAG_CTR; } while (0)
-#define CTR_MODIFIED(desc) do { (desc).regout[3] |= REGFLAG_CTR; } while (0)
-#define LR_USED(desc) do { (desc).regin[3] |= REGFLAG_LR; } while (0)
-#define LR_MODIFIED(desc) do { (desc).regout[3] |= REGFLAG_LR; } while (0)
+#define CTR_USED(desc) do { (desc).regin.set(REG_BIT_CTR); } while (0)
+#define CTR_MODIFIED(desc) do { (desc).regout.set(REG_BIT_CTR); } while (0)
+#define LR_USED(desc) do { (desc).regin.set(REG_BIT_LR); } while (0)
+#define LR_MODIFIED(desc) do { (desc).regout.set(REG_BIT_LR); } while (0)
-#define FPSCR_USED(desc, x) do { (desc).regin[3] |= REGFLAG_FPSCR(x); } while (0)
-#define FPSCR_MODIFIED(desc, x) do { (desc).regout[3] |= REGFLAG_FPSCR(x); } while (0)
+#define FPSCR_USED(desc, x) do { (desc).regin.set(REG_BIT_FPSCR0 + x); } while (0)
+#define FPSCR_MODIFIED(desc, x) do { (desc).regout.set(REG_BIT_FPSCR0 + x); } while (0)
@@ -57,11 +60,22 @@
//-------------------------------------------------
ppc_device::frontend::frontend(ppc_device &ppc, uint32_t window_start, uint32_t window_end, uint32_t max_sequence)
- : drc_frontend(ppc, window_start, window_end, max_sequence)
+ : drc_frontend_base(ppc.space_config(AS_PROGRAM)->page_shift(), window_start, window_end, max_sequence)
, m_ppc(ppc)
{
}
+ppc_device::frontend::~frontend()
+{
+}
+
+ppc_device::opcode_desc const *ppc_device::frontend::describe_code(offs_t startpc)
+{
+ return do_describe_code(
+ [this] (opcode_desc &desc, opcode_desc const *prev) { return describe(desc, prev); },
+ startpc);
+}
+
//-------------------------------------------------
// describe - build a description of a single
@@ -70,7 +84,6 @@ ppc_device::frontend::frontend(ppc_device &ppc, uint32_t window_start, uint32_t
bool ppc_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev)
{
- uint32_t op, opswitch;
int regnum;
// compute the physical PC
@@ -78,19 +91,23 @@ bool ppc_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev)
{
// uh-oh: a page fault; leave the description empty and just if this is the first instruction, leave it empty and
// mark as needing to validate; otherwise, just end the sequence here
- desc.flags |= OPFLAG_VALIDATE_TLB | OPFLAG_CAN_CAUSE_EXCEPTION | OPFLAG_COMPILER_PAGE_FAULT | OPFLAG_VIRTUAL_NOOP | OPFLAG_END_SEQUENCE;
+ desc.set_validate_tlb();
+ desc.set_can_cause_exception();
+ desc.set_compiler_page_fault();
+ desc.set_virtual_noop();
+ desc.set_end_sequence();
return true;
}
// fetch the opcode
- op = desc.opptr.l[0] = m_ppc.m_pr32(desc.physpc);
+ const uint32_t op = desc.opptr = m_ppc.m_pr32(desc.physpc);
// all instructions are 4 bytes and default to a single cycle each
desc.length = 4;
desc.cycles = 1;
// parse the instruction
- opswitch = op >> 26;
+ const uint32_t opswitch = op >> 26;
switch (opswitch)
{
case 0x02: // TDI - 64-bit only
@@ -101,7 +118,7 @@ bool ppc_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev)
case 0x03: // TWI
GPR_USED(desc, G_RA(op));
- desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.set_can_cause_exception();
if (is_603_class())
desc.cycles = 2; // 603
return true;
@@ -162,7 +179,7 @@ bool ppc_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev)
{
CR_BIT_USED(desc, G_BI(op));
// branch folding
- if (prev == nullptr || prev->regout[2] == 0)
+ if (prev == nullptr || REGFLAG_CR(prev->regout) == 0)
desc.cycles = 0;
}
if (!(G_BO(op) & 0x04))
@@ -173,9 +190,14 @@ bool ppc_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev)
if (op & M_LK)
LR_MODIFIED(desc);
if ((G_BO(op) & 0x14) == 0x14)
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ {
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
+ }
else
- desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+ {
+ desc.set_is_conditional_branch();
+ }
desc.targetpc = (int16_t)(G_BD(op) << 2) + ((op & M_AA) ? 0 : desc.pc);
if (desc.targetpc == desc.pc && desc.cycles == 0)
desc.cycles = 1;
@@ -184,7 +206,7 @@ bool ppc_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev)
case 0x11: // SC
if (!(m_ppc.m_cap & (PPCCAP_OEA | PPCCAP_4XX)))
return false;
- desc.flags |= OPFLAG_WILL_CAUSE_EXCEPTION;
+ desc.set_will_cause_exception();
if (is_601_class())
desc.cycles = 16; // 601
else if (is_603_class())
@@ -196,7 +218,8 @@ bool ppc_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev)
case 0x12: // Bx
if (op & M_LK)
LR_MODIFIED(desc);
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
desc.targetpc = ((int32_t)(G_LI(op) << 8) >> 6) + ((op & M_AA) ? 0 : desc.pc);
// branch folding
if (desc.targetpc != desc.pc)
@@ -263,7 +286,7 @@ bool ppc_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev)
case 0x2a: // LHA
GPR_USED_OR_ZERO(desc, G_RA(op));
GPR_MODIFIED(desc, G_RD(op));
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_reads_memory();
return true;
case 0x21: // LWZU
@@ -275,7 +298,7 @@ bool ppc_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev)
GPR_USED(desc, G_RA(op));
GPR_MODIFIED(desc, G_RD(op));
GPR_MODIFIED(desc, G_RA(op));
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_reads_memory();
return true;
case 0x24: // STW
@@ -283,7 +306,7 @@ bool ppc_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev)
case 0x2c: // STH
GPR_USED_OR_ZERO(desc, G_RA(op));
GPR_USED(desc, G_RS(op));
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_writes_memory();
return true;
case 0x25: // STWU
@@ -294,7 +317,7 @@ bool ppc_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev)
GPR_USED(desc, G_RA(op));
GPR_USED(desc, G_RS(op));
GPR_MODIFIED(desc, G_RA(op));
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_writes_memory();
return true;
case 0x2e: // LMW
@@ -305,7 +328,7 @@ bool ppc_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev)
if (regnum != G_RA(op) || ((m_ppc.m_cap & PPCCAP_4XX) && regnum == 31))
GPR_MODIFIED(desc, regnum);
}
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_reads_memory();
desc.cycles = 32 - G_RD(op);
return true;
@@ -313,7 +336,7 @@ bool ppc_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev)
GPR_USED_OR_ZERO(desc, G_RA(op));
for (regnum = G_RS(op); regnum < 32; regnum++)
GPR_USED(desc, regnum);
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_writes_memory();
desc.cycles = 32 - G_RS(op);
return true;
@@ -323,7 +346,7 @@ bool ppc_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev)
return false;
GPR_USED_OR_ZERO(desc, G_RA(op));
FPR_MODIFIED(desc, G_RD(op));
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_reads_memory();
return true;
case 0x31: // LFSU
@@ -335,7 +358,7 @@ bool ppc_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev)
GPR_USED(desc, G_RA(op));
GPR_MODIFIED(desc, G_RA(op));
FPR_MODIFIED(desc, G_RD(op));
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_reads_memory();
return true;
case 0x34: // STFS
@@ -344,7 +367,7 @@ bool ppc_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev)
return false;
GPR_USED_OR_ZERO(desc, G_RA(op));
FPR_USED(desc, G_RS(op));
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_writes_memory();
return true;
case 0x35: // STFSU
@@ -356,7 +379,7 @@ bool ppc_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev)
GPR_USED(desc, G_RA(op));
GPR_MODIFIED(desc, G_RA(op));
FPR_USED(desc, G_RS(op));
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_writes_memory();
return true;
case 0x3b: // 0x3b group
@@ -386,7 +409,7 @@ bool ppc_device::frontend::describe_13(uint32_t op, opcode_desc &desc, const opc
CR_USED(desc, G_CRFS(op));
CR_MODIFIED(desc, G_CRFD(op));
// CR logical folding
- if (prev == nullptr || prev->regout[2] == 0)
+ if (prev == nullptr || REGFLAG_CR(prev->regout) == 0)
desc.cycles = 0;
return true;
@@ -402,9 +425,14 @@ bool ppc_device::frontend::describe_13(uint32_t op, opcode_desc &desc, const opc
if (op & M_LK)
LR_MODIFIED(desc);
if ((G_BO(op) & 0x14) == 0x14)
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ {
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
+ }
else
- desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+ {
+ desc.set_is_conditional_branch();
+ }
desc.targetpc = BRANCH_TARGET_DYNAMIC;
return true;
@@ -420,14 +448,18 @@ bool ppc_device::frontend::describe_13(uint32_t op, opcode_desc &desc, const opc
CR_BIT_USED(desc, G_CRBB(op));
CR_BIT_MODIFIED(desc, G_CRBD(op));
// CR logical folding
- if (prev == nullptr || prev->regout[2] == 0)
+ if (prev == nullptr || REGFLAG_CR(prev->regout) == 0)
desc.cycles = 0;
return true;
case 0x032: // RFI
if (!(m_ppc.m_cap & (PPCCAP_OEA | PPCCAP_4XX)))
return false;
- desc.flags |= OPFLAG_PRIVILEGED | OPFLAG_CAN_CHANGE_MODES | OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE | OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.set_is_unconditional_branch();
+ desc.set_can_cause_exception();
+ desc.set_end_sequence();
+ desc.set_privileged();
+ desc.set_can_change_modes();
desc.targetpc = BRANCH_TARGET_DYNAMIC;
if (is_601_class())
desc.cycles = 13; // 601
@@ -440,7 +472,11 @@ bool ppc_device::frontend::describe_13(uint32_t op, opcode_desc &desc, const opc
case 0x033: // RFCI
if (!(m_ppc.m_cap & PPCCAP_4XX))
return false;
- desc.flags |= OPFLAG_PRIVILEGED | OPFLAG_CAN_CHANGE_MODES | OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE | OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.set_is_unconditional_branch();
+ desc.set_can_cause_exception();
+ desc.set_end_sequence();
+ desc.set_privileged();
+ desc.set_can_change_modes();
desc.targetpc = BRANCH_TARGET_DYNAMIC;
return true;
@@ -460,9 +496,14 @@ bool ppc_device::frontend::describe_13(uint32_t op, opcode_desc &desc, const opc
if (op & M_LK)
LR_MODIFIED(desc);
if ((G_BO(op) & 0x14) == 0x14)
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ {
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
+ }
else
- desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+ {
+ desc.set_is_conditional_branch();
+ }
desc.targetpc = BRANCH_TARGET_DYNAMIC;
return true;
}
@@ -523,7 +564,7 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc
case 0x004: // TW
GPR_USED(desc, G_RA(op));
GPR_USED(desc, G_RB(op));
- desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.set_can_cause_exception();
if (is_603_class())
desc.cycles = 2; // 603
return true;
@@ -736,7 +777,7 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc
GPR_USED_OR_ZERO(desc, G_RA(op));
GPR_USED(desc, G_RB(op));
GPR_MODIFIED(desc, G_RD(op));
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_reads_memory();
return true;
case 0x018: // SLWx
@@ -800,7 +841,8 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc
return false;
GPR_USED_OR_ZERO(desc, G_RA(op));
GPR_USED(desc, G_RB(op));
- desc.flags |= OPFLAG_PRIVILEGED | OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.set_can_cause_exception();
+ desc.set_privileged();
return true;
case 0x037: // LWZUX
@@ -813,7 +855,7 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc
GPR_USED(desc, G_RB(op));
GPR_MODIFIED(desc, G_RD(op));
GPR_MODIFIED(desc, G_RA(op));
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_reads_memory();
return true;
case 0x153: // MFSPR
@@ -831,7 +873,10 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc
XER_SO_USED(desc);
}
if (spr & 0x010)
- desc.flags |= OPFLAG_PRIVILEGED | OPFLAG_CAN_CAUSE_EXCEPTION;
+ {
+ desc.set_can_cause_exception();
+ desc.set_privileged();
+ }
if ((m_ppc.m_cap & PPCCAP_4XX) && spr == SPR4XX_TBLU)
desc.cycles = POWERPC_COUNT_READ_TBL;
else if ((m_ppc.m_cap & PPCCAP_VEA) && spr == SPRVEA_TBL_R)
@@ -842,20 +887,24 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc
case 0x053: // MFMSR
GPR_MODIFIED(desc, G_RD(op));
- desc.flags |= OPFLAG_PRIVILEGED | OPFLAG_CAN_CAUSE_EXCEPTION | OPFLAG_CAN_EXPOSE_EXTERNAL_INT;
+ desc.set_can_cause_exception();
+ desc.set_can_expose_external_int();
+ desc.set_privileged();
if (is_601_class())
desc.cycles = 2; // 601
return true;
case 0x253: // MFSR
GPR_MODIFIED(desc, G_RD(op));
- desc.flags |= OPFLAG_PRIVILEGED | OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.set_can_cause_exception();
+ desc.set_privileged();
return true;
case 0x293: // MFSRIN
GPR_USED(desc, G_RB(op));
GPR_MODIFIED(desc, G_RD(op));
- desc.flags |= OPFLAG_PRIVILEGED | OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.set_can_cause_exception();
+ desc.set_privileged();
return true;
case 0x173: // MFTB
@@ -900,7 +949,10 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc
case 0x092: // MTMSR
GPR_USED(desc, G_RS(op));
- desc.flags |= OPFLAG_PRIVILEGED | OPFLAG_CAN_CAUSE_EXCEPTION | OPFLAG_CAN_CHANGE_MODES | OPFLAG_END_SEQUENCE;
+ desc.set_can_cause_exception();
+ desc.set_end_sequence();
+ desc.set_privileged();
+ desc.set_can_change_modes();
if (is_601_class())
desc.cycles = 17; // 601
else if (is_603_class())
@@ -911,7 +963,8 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc
if (!(m_ppc.m_cap & PPCCAP_OEA))
return false;
GPR_USED(desc, G_RS(op));
- desc.flags |= OPFLAG_PRIVILEGED | OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.set_can_cause_exception();
+ desc.set_privileged();
return true;
case 0x1d3: // MTSPR
@@ -929,7 +982,10 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc
XER_SO_MODIFIED(desc);
}
if (spr & 0x010)
- desc.flags |= OPFLAG_PRIVILEGED | OPFLAG_CAN_CAUSE_EXCEPTION;
+ {
+ desc.set_can_cause_exception();
+ desc.set_privileged();
+ }
return true;
case 0x1b6: // ECOWX
@@ -945,7 +1001,7 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc
GPR_USED_OR_ZERO(desc, G_RA(op));
GPR_USED(desc, G_RB(op));
GPR_USED(desc, G_RS(op));
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_writes_memory();
return true;
case 0x0b7: // STWUX
@@ -957,7 +1013,7 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc
GPR_USED(desc, G_RB(op));
GPR_USED(desc, G_RS(op));
GPR_MODIFIED(desc, G_RA(op));
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_writes_memory();
return true;
case 0x0f2: // MTSRIN
@@ -965,27 +1021,31 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc
return false;
GPR_USED(desc, G_RS(op));
GPR_USED(desc, G_RB(op));
- desc.flags |= OPFLAG_PRIVILEGED | OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.set_can_cause_exception();
+ desc.set_privileged();
return true;
case 0x132: // TLBIE
if (!(m_ppc.m_cap & PPCCAP_OEA))
return false;
GPR_USED(desc, G_RB(op));
- desc.flags |= OPFLAG_PRIVILEGED | OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.set_can_cause_exception();
+ desc.set_privileged();
return true;
case 0x172: // TLBIA
if (!(m_ppc.m_cap & PPCCAP_OEA) || (m_ppc.m_cap & PPCCAP_603_MMU))
return false;
- desc.flags |= OPFLAG_PRIVILEGED | OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.set_can_cause_exception();
+ desc.set_privileged();
return true;
case 0x3d2: // TLBLD
case 0x3f2: // TLBLI
if (!(m_ppc.m_cap & PPCCAP_603_MMU) && !is_602_class())
return false;
- desc.flags |= OPFLAG_PRIVILEGED | OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.set_can_cause_exception();
+ desc.set_privileged();
return true;
case 0x200: // MCRXR
@@ -1004,7 +1064,7 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc
XER_COUNT_USED(desc);
for (regnum = 0; regnum < 32; regnum++)
GPR_MODIFIED(desc, regnum);
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_reads_memory();
return true;
case 0x217: // LFSX
@@ -1014,13 +1074,14 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc
GPR_USED_OR_ZERO(desc, G_RA(op));
GPR_USED(desc, G_RB(op));
FPR_MODIFIED(desc, G_RD(op));
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_reads_memory();
return true;
case 0x236: // TLBSYNC
if (!(m_ppc.m_cap & PPCCAP_OEA))
return false;
- desc.flags |= OPFLAG_PRIVILEGED | OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.set_can_cause_exception();
+ desc.set_privileged();
return true;
case 0x256: // SYNC
@@ -1041,14 +1102,14 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc
GPR_USED(desc, G_RB(op));
GPR_MODIFIED(desc, G_RA(op));
FPR_MODIFIED(desc, G_RD(op));
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_reads_memory();
return true;
case 0x255: // LSWI
GPR_USED_OR_ZERO(desc, G_RA(op));
for (regnum = 0; regnum < ((G_NB(op) - 1) & 0x1f) + 1; regnum += 4)
GPR_MODIFIED(desc, (G_RD(op) + regnum / 4) % 32);
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_reads_memory();
desc.cycles = (((G_NB(op) - 1) & 0x1f) + 1 + 3) / 4;
return true;
@@ -1058,14 +1119,14 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc
XER_COUNT_USED(desc);
for (regnum = 0; regnum < 32; regnum++)
GPR_USED(desc, regnum);
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_writes_memory();
return true;
case 0x2d5: // STSWI
GPR_USED_OR_ZERO(desc, G_RA(op));
for (regnum = 0; regnum < ((G_NB(op) - 1) & 0x1f) + 1; regnum += 4)
GPR_USED(desc, (G_RD(op) + regnum / 4) % 32);
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_writes_memory();
desc.cycles = (((G_NB(op) - 1) & 0x1f) + 1 + 3) / 4;
return true;
@@ -1077,7 +1138,7 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc
GPR_USED_OR_ZERO(desc, G_RA(op));
GPR_USED(desc, G_RB(op));
FPR_USED(desc, G_RS(op));
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_writes_memory();
return true;
case 0x2b7: // STFSUX
@@ -1090,7 +1151,7 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc
GPR_USED(desc, G_RB(op));
GPR_MODIFIED(desc, G_RA(op));
FPR_USED(desc, G_RS(op));
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_writes_memory();
return true;
case 0x338: // SRAWIx
@@ -1109,7 +1170,7 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc
return false;
GPR_USED_OR_ZERO(desc, G_RA(op));
GPR_USED(desc, G_RB(op));
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_writes_memory();
return true;
case 0x106: // ICBT
@@ -1119,7 +1180,8 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc
return false;
GPR_USED_OR_ZERO(desc, G_RA(op));
GPR_USED(desc, G_RB(op));
- desc.flags |= OPFLAG_PRIVILEGED | OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.set_can_cause_exception();
+ desc.set_privileged();
return true;
case 0x1e6: // DCREAD
@@ -1129,42 +1191,48 @@ bool ppc_device::frontend::describe_1f(uint32_t op, opcode_desc &desc, const opc
GPR_USED_OR_ZERO(desc, G_RA(op));
GPR_USED(desc, G_RB(op));
GPR_MODIFIED(desc, G_RT(op));
- desc.flags |= OPFLAG_PRIVILEGED | OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.set_can_cause_exception();
+ desc.set_privileged();
return true;
case 0x143: // MFDCR
if (!(m_ppc.m_cap & PPCCAP_4XX))
return false;
GPR_MODIFIED(desc, G_RD(op));
- desc.flags |= OPFLAG_PRIVILEGED | OPFLAG_CAN_CAUSE_EXCEPTION;
+ desc.set_can_cause_exception();
+ desc.set_privileged();
return true;
case 0x1c3: // MTDCR
if (!(m_ppc.m_cap & PPCCAP_4XX))
return false;
GPR_USED(desc, G_RS(op));
- desc.flags |= OPFLAG_PRIVILEGED | OPFLAG_CAN_CAUSE_EXCEPTION | OPFLAG_CAN_EXPOSE_EXTERNAL_INT;
+ desc.set_can_cause_exception();
+ desc.set_can_expose_external_int();
+ desc.set_privileged();
return true;
case 0x083: // WRTEE
if (!(m_ppc.m_cap & PPCCAP_4XX))
return false;
GPR_USED(desc, G_RS(op));
- desc.flags |= OPFLAG_CAN_EXPOSE_EXTERNAL_INT;
+ desc.set_can_expose_external_int();
return true;
case 0x0a3: // WRTEEI
if (!(m_ppc.m_cap & PPCCAP_4XX))
return false;
if (op & MSR_EE)
- desc.flags |= OPFLAG_CAN_EXPOSE_EXTERNAL_INT;
+ desc.set_can_expose_external_int();
return true;
case 0x254: // ESA
case 0x274: // DSA
if (!is_602_class())
return false;
- desc.flags |= OPFLAG_CAN_CHANGE_MODES | OPFLAG_CAN_CAUSE_EXCEPTION | OPFLAG_END_SEQUENCE;
+ desc.set_can_cause_exception();
+ desc.set_end_sequence();
+ desc.set_can_change_modes();
return true;
case 0x14b: // DIV (POWER)
diff --git a/src/devices/cpu/powerpc/ppcfe.h b/src/devices/cpu/powerpc/ppcfe.h
index 40b82bd8756..840a72c448f 100644
--- a/src/devices/cpu/powerpc/ppcfe.h
+++ b/src/devices/cpu/powerpc/ppcfe.h
@@ -16,42 +16,101 @@
#include "cpu/drcfe.h"
+#include <bitset>
+
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
-class ppc_device::frontend : public drc_frontend
+class ppc_device::opcode_desc : public opcode_desc_base<opcode_desc, 128>
{
public:
- // register flags 0
- static constexpr u32 REGFLAG_R(unsigned n) { return 1U << n; }
- static constexpr u32 REGFLAG_RZ(unsigned n) { return !n ? 0U : REGFLAG_R(n); }
-
- // register flags 1
- static constexpr u32 REGFLAG_FR(unsigned n) { return 1U << n; }
-
- // register flags 2
- static constexpr u32 REGFLAG_CR(unsigned n) { return 0xf0000000U >> (4 * n); }
- static constexpr u32 REGFLAG_CR_BIT(unsigned n) { return 0x80000000U >> n; }
-
- // register flags 3
- static constexpr u32 REGFLAG_XER_CA = 1U << 0;
- static constexpr u32 REGFLAG_XER_OV = 1U << 1;
- static constexpr u32 REGFLAG_XER_SO = 1U << 2;
- static constexpr u32 REGFLAG_XER_COUNT = 1U << 3;
- static constexpr u32 REGFLAG_CTR = 1U << 4;
- static constexpr u32 REGFLAG_LR = 1U << 5;
- static constexpr u32 REGFLAG_FPSCR(unsigned n) { return 1U << (6 + n); }
+ offs_t physpc; // physical PC of this opcode
+
+ u32 opptr; // copy of opcode
+
+ u32 cycles; // number of cycles needed to execute
+
+ void set_can_expose_external_int() { m_extra_flags.set(CAN_EXPOSE_EXTERNAL_INT); }
+ void set_privileged() { m_extra_flags.set(PRIVILEGED); }
+ void set_compiler_unmapped() { m_extra_flags.set(COMPILER_UNMAPPED); }
+ void set_can_change_modes() { m_extra_flags.set(CAN_CHANGE_MODES); }
+ void set_reads_memory() { m_extra_flags.set(READS_MEMORY); }
+ void set_writes_memory() { m_extra_flags.set(WRITES_MEMORY); }
+
+ bool can_expose_external_int() const { return m_extra_flags[CAN_EXPOSE_EXTERNAL_INT]; }
+ bool privileged() const { return m_extra_flags[PRIVILEGED]; }
+ bool compiler_unmapped() const { return m_extra_flags[COMPILER_UNMAPPED]; }
+ bool can_change_modes() const { return m_extra_flags[CAN_CHANGE_MODES]; }
+ bool reads_memory() const { return m_extra_flags[READS_MEMORY]; }
+ bool writes_memory() const { return m_extra_flags[WRITES_MEMORY]; }
+
+ void reset(offs_t curpc, bool in_delay_slot)
+ {
+ opcode_desc_base::reset(curpc, in_delay_slot);
+
+ physpc = curpc;
+ opptr = 0;
+ cycles = 0;
+ m_extra_flags.reset();
+ }
+
+protected:
+ enum
+ {
+ CAN_EXPOSE_EXTERNAL_INT = 0,
+ PRIVILEGED,
+ COMPILER_UNMAPPED,
+ CAN_CHANGE_MODES,
+ READS_MEMORY,
+ WRITES_MEMORY,
+
+ EXTRA_FLAG_COUNT
+ };
+
+ std::bitset<EXTRA_FLAG_COUNT> m_extra_flags;
+};
+
+class ppc_device::frontend : public drc_frontend_base<opcode_desc>
+{
+public:
+ static constexpr bool REGFLAG_R(const opcode_desc::regmask &r, unsigned n) { return r[REG_BIT_R0 + n]; }
+ static constexpr bool REGFLAG_RZ(const opcode_desc::regmask &r, unsigned n) { return n && REGFLAG_R(r, n); }
+ static constexpr bool REGFLAG_FR(const opcode_desc::regmask &r, unsigned n) { return r[REG_BIT_FR0 + n]; }
+ static constexpr uint32_t REGFLAG_CR(const opcode_desc::regmask &r) { return uint32_t(((r << 32) >> (128 - 32)).to_ulong()); }
+ static constexpr uint8_t REGFLAG_CR(const opcode_desc::regmask &r, unsigned n) { return uint8_t(((r << ((4 * n) + 32)) >> (128 - 4)).to_ulong()); }
+ static constexpr bool REGFLAG_CR_BIT(const opcode_desc::regmask &r, unsigned n) { return r[64 + 31 - n]; }
+ static constexpr bool REGFLAG_XER_CA(const opcode_desc::regmask &r) { return r[REG_BIT_XER_CA]; }
+ static constexpr bool REGFLAG_XER_OV(const opcode_desc::regmask &r) { return r[REG_BIT_XER_OV]; }
+ static constexpr bool REGFLAG_XER_SO(const opcode_desc::regmask &r) { return r[REG_BIT_XER_SO]; }
+ static constexpr bool REGFLAG_XER_COUNT(const opcode_desc::regmask &r) { return r[REG_BIT_XER_COUNT]; }
+ static constexpr bool REGFLAG_CTR(const opcode_desc::regmask &r) { return r[REG_BIT_CTR]; }
+ static constexpr bool REGFLAG_LR(const opcode_desc::regmask &r) { return r[REG_BIT_LR]; }
+ static constexpr bool REGFLAG_FPSCR(const opcode_desc::regmask &r, unsigned n) { return r[REG_BIT_FPSCR0 + n]; }
// construction/destruction
frontend(ppc_device &ppc, uint32_t window_start, uint32_t window_end, uint32_t max_sequence);
+ ~frontend();
+
+ opcode_desc const *describe_code(offs_t startpc);
protected:
- // required overrides
- virtual bool describe(opcode_desc &desc, const opcode_desc *prev) override;
+ enum
+ {
+ REG_BIT_R0 = 0,
+ REG_BIT_FR0 = 32,
+ REG_BIT_XER_CA = 96,
+ REG_BIT_XER_OV,
+ REG_BIT_XER_SO,
+ REG_BIT_XER_COUNT,
+ REG_BIT_CTR,
+ REG_BIT_LR,
+ REG_BIT_FPSCR0
+ };
+
+ bool describe(opcode_desc &desc, const opcode_desc *prev);
-private:
// inlines
uint32_t compute_spr(uint32_t spr) const { return ((spr >> 5) | (spr << 5)) & 0x3ff; }
bool is_403_class() const { return (m_ppc.m_flavor == ppc_device::PPC_MODEL_403GA || m_ppc.m_flavor == ppc_device::PPC_MODEL_403GB || m_ppc.m_flavor == ppc_device::PPC_MODEL_403GC || m_ppc.m_flavor == ppc_device::PPC_MODEL_403GCX || m_ppc.m_flavor == ppc_device::PPC_MODEL_405GP); }
@@ -69,5 +128,4 @@ private:
ppc_device &m_ppc;
};
-
#endif // MAME_CPU_POWERPC_PPCFE_H
diff --git a/src/devices/cpu/sh/sh.cpp b/src/devices/cpu/sh/sh.cpp
index 4c1d987f639..c507410d759 100644
--- a/src/devices/cpu/sh/sh.cpp
+++ b/src/devices/cpu/sh/sh.cpp
@@ -5,6 +5,7 @@
#include "sh.h"
#include "sh_dasm.h"
+#include "sh_fe.h"
#include "cpu/drcumlsh.h"
@@ -1983,16 +1984,6 @@ void sh_common_execution::sh2drc_add_fastram(offs_t start, offs_t end, uint8_t r
***************************************************************************/
/*-------------------------------------------------
- epc - compute the exception PC from a
- descriptor
--------------------------------------------------*/
-
-uint32_t sh_common_execution::epc(const opcode_desc *desc)
-{
- return (desc->flags & OPFLAG_IN_DELAY_SLOT) ? (desc->pc - 1) : desc->pc;
-}
-
-/*-------------------------------------------------
alloc_handle - allocate a handle if not
already allocated
-------------------------------------------------*/
@@ -2043,52 +2034,49 @@ void sh_common_execution::save_fast_iregs(drcuml_block &block)
flags
-------------------------------------------------*/
-const char *sh_common_execution::log_desc_flags_to_string(uint32_t flags)
+const char *sh_common_execution::log_desc_flags_to_string(const opcode_desc &desc)
{
static char tempbuf[30];
char *dest = tempbuf;
/* branches */
- if (flags & OPFLAG_IS_UNCONDITIONAL_BRANCH)
+ if (desc.is_unconditional_branch())
*dest++ = 'U';
- else if (flags & OPFLAG_IS_CONDITIONAL_BRANCH)
+ else if (desc.is_conditional_branch())
*dest++ = 'C';
else
*dest++ = '.';
/* intrablock branches */
- *dest++ = (flags & OPFLAG_INTRABLOCK_BRANCH) ? 'i' : '.';
+ *dest++ = desc.intrablock_branch() ? 'i' : '.';
/* branch targets */
- *dest++ = (flags & OPFLAG_IS_BRANCH_TARGET) ? 'B' : '.';
+ *dest++ = desc.is_branch_target() ? 'B' : '.';
/* delay slots */
- *dest++ = (flags & OPFLAG_IN_DELAY_SLOT) ? 'D' : '.';
+ *dest++ = desc.in_delay_slot() ? 'D' : '.';
/* exceptions */
- if (flags & OPFLAG_WILL_CAUSE_EXCEPTION)
+ if (desc.will_cause_exception())
*dest++ = 'E';
- else if (flags & OPFLAG_CAN_CAUSE_EXCEPTION)
+ else if (desc.can_cause_exception())
*dest++ = 'e';
else
*dest++ = '.';
/* read/write */
- if (flags & OPFLAG_READS_MEMORY)
+ if (desc.reads_memory())
*dest++ = 'R';
- else if (flags & OPFLAG_WRITES_MEMORY)
+ else if (desc.writes_memory())
*dest++ = 'W';
else
*dest++ = '.';
/* TLB validation */
- *dest++ = (flags & OPFLAG_VALIDATE_TLB) ? 'V' : '.';
-
- /* TLB modification */
- *dest++ = (flags & OPFLAG_MODIFIES_TRANSLATION) ? 'T' : '.';
+ *dest++ = desc.validate_tlb() ? 'V' : '.';
/* redispatch */
- *dest++ = (flags & OPFLAG_REDISPATCH) ? 'R' : '.';
+ *dest++ = desc.redispatch() ? 'R' : '.';
return tempbuf;
}
@@ -2097,66 +2085,65 @@ const char *sh_common_execution::log_desc_flags_to_string(uint32_t flags)
log_register_list - log a list of GPR registers
-------------------------------------------------*/
-void sh_common_execution::log_register_list(const char *string, const uint32_t *reglist, const uint32_t *regnostarlist)
+void sh_common_execution::log_register_list(const char *string, const std::bitset<32> &reglist, const std::bitset<32> *regnostarlist)
{
int count = 0;
- int regnum;
/* skip if nothing */
- if (reglist[0] == 0 && reglist[1] == 0 && reglist[2] == 0)
+ if (reglist.none())
return;
m_drcuml->log_printf("[%s:", string);
- for (regnum = 0; regnum < 16; regnum++)
+ for (int regnum = 0; regnum < 16; regnum++)
{
- if (reglist[0] & REGFLAG_R(regnum))
+ if (reglist[opcode_desc::REG_R0 + regnum])
{
m_drcuml->log_printf("%sr%d", (count++ == 0) ? "" : ",", regnum);
- if (regnostarlist != nullptr && !(regnostarlist[0] & REGFLAG_R(regnum)))
+ if (regnostarlist && !(*regnostarlist)[opcode_desc::REG_R0 + regnum])
m_drcuml->log_printf("*");
}
}
- if (reglist[1] & REGFLAG_PR)
+ if (reglist[opcode_desc::REG_PR])
{
m_drcuml->log_printf("%spr", (count++ == 0) ? "" : ",");
- if (regnostarlist != nullptr && !(regnostarlist[1] & REGFLAG_PR))
+ if (regnostarlist && !(*regnostarlist)[opcode_desc::REG_PR])
m_drcuml->log_printf("*");
}
- if (reglist[1] & REGFLAG_SR)
+ if (reglist[opcode_desc::REG_SR])
{
m_drcuml->log_printf("%ssr", (count++ == 0) ? "" : ",");
- if (regnostarlist != nullptr && !(regnostarlist[1] & REGFLAG_SR))
+ if (regnostarlist && !(*regnostarlist)[opcode_desc::REG_SR])
m_drcuml->log_printf("*");
}
- if (reglist[1] & REGFLAG_MACL)
+ if (reglist[opcode_desc::REG_MACL])
{
m_drcuml->log_printf("%smacl", (count++ == 0) ? "" : ",");
- if (regnostarlist != nullptr && !(regnostarlist[1] & REGFLAG_MACL))
+ if (regnostarlist && !(*regnostarlist)[opcode_desc::REG_MACL])
m_drcuml->log_printf("*");
}
- if (reglist[1] & REGFLAG_MACH)
+ if (reglist[opcode_desc::REG_MACH])
{
m_drcuml->log_printf("%smach", (count++ == 0) ? "" : ",");
- if (regnostarlist != nullptr && !(regnostarlist[1] & REGFLAG_MACH))
+ if (regnostarlist && !(*regnostarlist)[opcode_desc::REG_MACH])
m_drcuml->log_printf("*");
}
- if (reglist[1] & REGFLAG_GBR)
+ if (reglist[opcode_desc::REG_GBR])
{
m_drcuml->log_printf("%sgbr", (count++ == 0) ? "" : ",");
- if (regnostarlist != nullptr && !(regnostarlist[1] & REGFLAG_GBR))
+ if (regnostarlist && !(*regnostarlist)[opcode_desc::REG_GBR])
m_drcuml->log_printf("*");
}
- if (reglist[1] & REGFLAG_VBR)
+ if (reglist[opcode_desc::REG_VBR])
{
m_drcuml->log_printf("%svbr", (count++ == 0) ? "" : ",");
- if (regnostarlist != nullptr && !(regnostarlist[1] & REGFLAG_VBR))
+ if (regnostarlist && !(*regnostarlist)[opcode_desc::REG_VBR])
m_drcuml->log_printf("*");
}
@@ -2181,21 +2168,21 @@ void sh_common_execution::log_opcode_desc(const opcode_desc *desclist, int inden
/* disassemle the current instruction and output it to the log */
if (m_drcuml->logging() || m_drcuml->logging_native())
{
- if (desclist->flags & OPFLAG_VIRTUAL_NOOP)
+ if (desclist->virtual_noop())
stream << "<virtual nop>";
else
{
sh_disassembler sh2d(false);
- sh2d.dasm_one(stream, desclist->pc, desclist->opptr.w[0]);
+ sh2d.dasm_one(stream, desclist->pc, desclist->opptr);
}
}
else
stream << "???";
- m_drcuml->log_printf("%08X [%08X] t:%08X f:%s: %-30s", desclist->pc, desclist->physpc, desclist->targetpc, log_desc_flags_to_string(desclist->flags), stream.str().c_str());
+ m_drcuml->log_printf("%08X [%08X] t:%08X f:%s: %-30s", desclist->pc, desclist->physpc, desclist->targetpc, log_desc_flags_to_string(*desclist), stream.str());
/* output register states */
log_register_list("use", desclist->regin, nullptr);
- log_register_list("mod", desclist->regout, desclist->regreq);
+ log_register_list("mod", desclist->regout, &desclist->regreq);
m_drcuml->log_printf("\n");
/* if we have a delay slot, output it recursively */
@@ -2203,7 +2190,7 @@ void sh_common_execution::log_opcode_desc(const opcode_desc *desclist, int inden
log_opcode_desc(desclist->delay.first(), indent + 1);
/* at the end of a sequence add a dividing line */
- if (desclist->flags & OPFLAG_END_SEQUENCE)
+ if (desclist->end_sequence())
m_drcuml->log_printf("-----\n");
}
}
@@ -2330,7 +2317,7 @@ void sh_common_execution::code_compile_block(uint8_t mode, offs_t pc)
/* determine the last instruction in this sequence */
for (seqlast = seqhead; seqlast != nullptr; seqlast = seqlast->next())
- if (seqlast->flags & OPFLAG_END_SEQUENCE)
+ if (seqlast->end_sequence())
break;
assert(seqlast != nullptr);
@@ -2360,7 +2347,7 @@ void sh_common_execution::code_compile_block(uint8_t mode, offs_t pc)
generate_checksum_block(block, compiler, seqhead, seqlast);
/* label this instruction, if it may be jumped to locally */
- if (seqhead->flags & OPFLAG_IS_BRANCH_TARGET)
+ if (seqhead->is_branch_target())
{
UML_LABEL(block, seqhead->pc | 0x80000000); // label seqhead->pc | 0x80000000
}
@@ -2371,14 +2358,14 @@ void sh_common_execution::code_compile_block(uint8_t mode, offs_t pc)
generate_sequence_instruction(block, compiler, curdesc, 0xffffffff);
}
- /* if we need to return to the start, do it */
- if (seqlast->flags & OPFLAG_RETURN_TO_START)
+ if (seqlast->return_to_start())
{
+ // if we need to return to the start, do it
nextpc = pc;
}
- /* otherwise we just go to the next instruction */
else
{
+ // otherwise we just go to the next instruction
nextpc = seqlast->pc + (seqlast->skipslots + 1) * 2;
}
@@ -2459,38 +2446,39 @@ void sh_common_execution::generate_checksum_block(drcuml_block &block, compiler_
if (m_drcuml->logging())
block.append_comment("[Validation for %08X]", seqhead->pc); // comment
- /* loose verify or single instruction: just compare and fail */
if (!(m_drcoptions & SH2DRC_STRICT_VERIFY) || seqhead->next() == nullptr)
{
- if (!(seqhead->flags & OPFLAG_VIRTUAL_NOOP))
+ // loose verify or single instruction: just compare and fail
+ if (!seqhead->virtual_noop())
{
const void *base = m_prptr(seqhead->physpc);
UML_LOAD(block, I0, base, 0, SIZE_WORD, SCALE_x2); // load i0,base,word
- UML_CMP(block, I0, seqhead->opptr.w[0]); // cmp i0,*opptr
- UML_EXHc(block, COND_NE, *m_nocode, epc(seqhead)); // exne nocode,seqhead->pc
+ UML_CMP(block, I0, seqhead->opptr); // cmp i0,*opptr
+ UML_EXHc(block, COND_NE, *m_nocode, seqhead->epc()); // exne nocode,seqhead->pc
}
}
-
- /* full verification; sum up everything */
else
{
+ // full verification; sum up everything
uint32_t sum = 0;
const void *base = m_prptr(seqhead->physpc);
UML_LOAD(block, I0, base, 0, SIZE_WORD, SCALE_x4); // load i0,base,word
- sum += seqhead->opptr.w[0];
+ sum += seqhead->opptr;
for (curdesc = seqhead->next(); curdesc != seqlast->next(); curdesc = curdesc->next())
- if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP))
+ {
+ if (!curdesc->virtual_noop())
{
base = m_prptr(curdesc->physpc);
UML_LOAD(block, I1, base, 0, SIZE_WORD, SCALE_x2); // load i1,*opptr,word
UML_ADD(block, I0, I0, I1); // add i0,i0,i1
- sum += curdesc->opptr.w[0];
+ sum += curdesc->opptr;
}
+ }
UML_CMP(block, I0, sum); // cmp i0,sum
- UML_EXHc(block, COND_NE, *m_nocode, epc(seqhead)); // exne nocode,seqhead->pc
+ UML_EXHc(block, COND_NE, *m_nocode, seqhead->epc()); // exne nocode,seqhead->pc
}
}
@@ -2503,14 +2491,12 @@ void sh_common_execution::generate_checksum_block(drcuml_block &block, compiler_
void sh_common_execution::generate_sequence_instruction(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint32_t ovrpc)
{
- offs_t expc;
-
/* add an entry for the log */
- if (m_drcuml->logging() && !(desc->flags & OPFLAG_VIRTUAL_NOOP))
- log_add_disasm_comment(block, desc->pc, desc->opptr.w[0]);
+ if (m_drcuml->logging() && !desc->virtual_noop())
+ log_add_disasm_comment(block, desc->pc, desc->opptr);
/* set the PC map variable */
- expc = (desc->flags & OPFLAG_IN_DELAY_SLOT) ? desc->pc - 1 : desc->pc;
+ const offs_t expc = desc->epc();
UML_MAPVAR(block, MAPVAR_PC, expc); // mapvar PC,expc
/* accumulate total cycles */
@@ -2554,29 +2540,20 @@ void sh_common_execution::generate_sequence_instruction(drcuml_block &block, com
}
- /* if we hit an unmapped address, fatal error */
- if (desc->flags & OPFLAG_COMPILER_UNMAPPED)
- {
- UML_MOV(block, mem(&m_sh2_state->pc), desc->pc); // mov [pc],desc->pc
- save_fast_iregs(block);
- UML_EXIT(block, EXECUTE_UNMAPPED_CODE); // exit EXECUTE_UNMAPPED_CODE
- }
-
- /* if this is an invalid opcode, die */
- if (desc->flags & OPFLAG_INVALID_OPCODE)
+ if (desc->invalid_opcode())
{
+ // if this is an invalid opcode, die
fatalerror("SH2DRC: invalid opcode!\n");
}
-
- /* otherwise, unless this is a virtual no-op, it's a regular instruction */
- else if (!(desc->flags & OPFLAG_VIRTUAL_NOOP))
+ else if (!desc->virtual_noop())
{
- /* compile the instruction */
+ // otherwise, unless this is a virtual no-op, it's a regular instruction
+ // compile the instruction
if (!generate_opcode(block, compiler, desc, ovrpc))
{
// handle an illegal op
UML_MOV(block, mem(&m_sh2_state->pc), desc->pc); // mov [pc],desc->pc
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); // mov [arg0],opcode
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr); // mov [arg0],opcode
UML_CALLC(block, cfunc_unimplemented, this); // callc cfunc_unimplemented
}
}
@@ -2716,9 +2693,9 @@ bool sh_common_execution::generate_opcode(drcuml_block &block, compiler_state &c
{
uint32_t scratch, scratch2;
int32_t disp;
- uint16_t opcode = desc->opptr.w[0];
- uint8_t opswitch = opcode >> 12;
- int in_delay_slot = ((desc->flags & OPFLAG_IN_DELAY_SLOT) != 0);
+ const uint16_t opcode = desc->opptr;
+ const uint8_t opswitch = opcode >> 12;
+ const int in_delay_slot = desc->in_delay_slot();
//printf("generating %04x\n", opcode);
@@ -3073,7 +3050,7 @@ bool sh_common_execution::generate_group_3(drcuml_block &block, compiler_state &
case 4: // DIV1(Rm, Rn);
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_DIV1, this);
load_fast_iregs(block);
return true;
@@ -3111,7 +3088,7 @@ bool sh_common_execution::generate_group_3(drcuml_block &block, compiler_state &
case 11: // SUBV(Rm, Rn);
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_SUBV, this);
load_fast_iregs(block);
return true;
@@ -3125,7 +3102,7 @@ bool sh_common_execution::generate_group_3(drcuml_block &block, compiler_state &
case 15: // ADDV(Rm, Rn);
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_ADDV, this);
load_fast_iregs(block);
return true;
@@ -3755,7 +3732,7 @@ bool sh_common_execution::generate_group_0(drcuml_block &block, compiler_state &
if (m_cpu_type > CPU_TYPE_SH1)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_MAC_L, this);
load_fast_iregs(block);
return true;
@@ -3968,7 +3945,7 @@ bool sh_common_execution::generate_group_4(drcuml_block &block, compiler_state &
case 0x2f: // MAC_W(Rm, Rn);
case 0x3f: // MAC_W(Rm, Rn);
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_MAC_W, this);
load_fast_iregs(block);
return true;
diff --git a/src/devices/cpu/sh/sh.h b/src/devices/cpu/sh/sh.h
index 44023ac096e..3d726db11bd 100644
--- a/src/devices/cpu/sh/sh.h
+++ b/src/devices/cpu/sh/sh.h
@@ -6,9 +6,11 @@
#pragma once
-#include "cpu/drcfe.h"
#include "cpu/drcuml.h"
+#include <bitset>
+
+
/***************************************************************************
DEBUGGING
**************************************************************************/
@@ -70,16 +72,6 @@
#define Q_SHIFT 8
#define M_SHIFT 9
-#define REGFLAG_R(n) (1 << (n))
-
-/* register flags 1 */
-#define REGFLAG_PR (1 << 0)
-#define REGFLAG_MACL (1 << 1)
-#define REGFLAG_MACH (1 << 2)
-#define REGFLAG_GBR (1 << 3)
-#define REGFLAG_VBR (1 << 4)
-#define REGFLAG_SR (1 << 5)
-
/***************************************************************************
MACROS
***************************************************************************/
@@ -186,6 +178,9 @@ protected:
EXECUTE_RESET_CACHE = 3
};
+ class frontend;
+ class opcode_desc;
+
sh_common_execution(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, endianness_t endianness, address_map_constructor internal);
void ADD(uint32_t m, uint32_t n);
@@ -448,8 +443,8 @@ public:
void alloc_handle(uml::code_handle *&handleptr, const char *name);
void load_fast_iregs(drcuml_block &block);
void save_fast_iregs(drcuml_block &block);
- const char *log_desc_flags_to_string(uint32_t flags);
- void log_register_list(const char *string, const uint32_t *reglist, const uint32_t *regnostarlist);
+ const char *log_desc_flags_to_string(const opcode_desc &flags);
+ void log_register_list(const char *string, const std::bitset<32> &reglist, const std::bitset<32> *regnostarlist);
void log_opcode_desc(const opcode_desc *desclist, int indent);
void log_add_disasm_comment(drcuml_block &block, uint32_t pc, uint32_t op);
void generate_delay_slot(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint32_t ovrpc);
@@ -463,32 +458,8 @@ public:
protected:
- // device-level overrides
+ // device_t implementation
virtual void device_start() override ATTR_COLD;
};
-class sh_frontend : public drc_frontend
-{
-public:
- sh_frontend(sh_common_execution *device, uint32_t window_start, uint32_t window_end, uint32_t max_sequence);
-
-protected:
- virtual uint16_t read_word(opcode_desc &desc);
- virtual bool describe(opcode_desc &desc, const opcode_desc *prev) override;
-
-private:
- bool describe_group_2(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode);
- bool describe_group_3(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode);
- bool describe_group_6(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode);
- bool describe_group_8(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode);
- bool describe_group_12(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode);
-
-protected:
- virtual bool describe_group_0(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode);
- virtual bool describe_group_4(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode);
- virtual bool describe_group_15(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode) = 0;
-
- sh_common_execution *m_sh;
-};
-
#endif // MAME_CPU_SH_SH_H
diff --git a/src/devices/cpu/sh/sh2.cpp b/src/devices/cpu/sh/sh2.cpp
index ae8acd76ee4..fd4df324c72 100644
--- a/src/devices/cpu/sh/sh2.cpp
+++ b/src/devices/cpu/sh/sh2.cpp
@@ -15,7 +15,10 @@
#include "emu.h"
#include "sh2.h"
+
+#include "sh2fe.h"
#include "sh_dasm.h"
+
#include "cpu/drcumlsh.h"
//#define VERBOSE 1
@@ -34,6 +37,10 @@ sh2_device::sh2_device(const machine_config &mconfig, device_type type, const ch
m_isdrc = allow_drc();
}
+sh2_device::~sh2_device()
+{
+}
+
void sh2_device::device_start()
{
sh_common_execution::device_start();
@@ -492,7 +499,7 @@ void sh2_device::sh2_exception_internal(const char *message, int irqline, int ve
/////////
// DRC
-const opcode_desc* sh2_device::get_desclist(offs_t pc)
+const sh2_device::opcode_desc* sh2_device::get_desclist(offs_t pc)
{
return m_drcfe->describe_code(pc);
}
diff --git a/src/devices/cpu/sh/sh2.h b/src/devices/cpu/sh/sh2.h
index 7e7af7c7d1e..3aceb1ae522 100644
--- a/src/devices/cpu/sh/sh2.h
+++ b/src/devices/cpu/sh/sh2.h
@@ -19,19 +19,18 @@
#include "sh.h"
-class sh2_frontend;
-
class sh2_device : public sh_common_execution
{
- friend class sh2_frontend;
-
public:
void set_frt_input(int state) override {} // not every CPU needs this, let the ones that do override it
void func_fastirq(); // required for DRC, needs to be public to be accessible through non-classed static trampoline function
protected:
+ class sh2_frontend;
+
sh2_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int cpu_type, address_map_constructor internal_map, int addrlines, uint32_t address_mask);
+ virtual ~sh2_device();
void check_pending_irq(const char *message);
@@ -99,16 +98,4 @@ private:
int8_t m_irq_line_state[17];
};
-
-class sh2_frontend : public sh_frontend
-{
-public:
- sh2_frontend(sh_common_execution *device, uint32_t window_start, uint32_t window_end, uint32_t max_sequence);
-
-protected:
-
-private:
- virtual bool describe_group_15(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode) override;
-};
-
#endif // MAME_CPU_SH_SH2_H
diff --git a/src/devices/cpu/sh/sh2fe.cpp b/src/devices/cpu/sh/sh2fe.cpp
index b21ea334ba0..000ecbc8977 100644
--- a/src/devices/cpu/sh/sh2fe.cpp
+++ b/src/devices/cpu/sh/sh2fe.cpp
@@ -9,22 +9,21 @@
***************************************************************************/
#include "emu.h"
-#include "sh2.h"
-#include "cpu/drcfe.h"
+#include "sh2fe.h"
/***************************************************************************
INSTRUCTION PARSERS
***************************************************************************/
-sh2_frontend::sh2_frontend(sh_common_execution *device, uint32_t window_start, uint32_t window_end, uint32_t max_sequence)
- : sh_frontend(device, window_start, window_end, max_sequence)
+sh2_device::sh2_frontend::sh2_frontend(sh_common_execution *device, uint32_t window_start, uint32_t window_end, uint32_t max_sequence)
+ : frontend(device, window_start, window_end, max_sequence)
{
}
-bool sh2_frontend::describe_group_15(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode)
+bool sh2_device::sh2_frontend::describe_group_15(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode)
{
return true;
}
diff --git a/src/devices/cpu/sh/sh2fe.h b/src/devices/cpu/sh/sh2fe.h
new file mode 100644
index 00000000000..b58fa79e705
--- /dev/null
+++ b/src/devices/cpu/sh/sh2fe.h
@@ -0,0 +1,28 @@
+// license:BSD-3-Clause
+// copyright-holders:R. Belmont
+/***************************************************************************
+
+ sh2fe.cpp
+
+ Front end for SH-2 recompiler
+
+***************************************************************************/
+#ifndef MAME_CPU_SH_SH2FE_H
+#define MAME_CPU_SH_SH2FE_H
+
+#pragma once
+
+#include "sh2.h"
+#include "sh_fe.h"
+
+
+class sh2_device::sh2_frontend : public sh_common_execution::frontend
+{
+public:
+ sh2_frontend(sh_common_execution *device, uint32_t window_start, uint32_t window_end, uint32_t max_sequence);
+
+private:
+ virtual bool describe_group_15(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode) override;
+};
+
+#endif // MAME_CPU_SH_SH2FE_H
diff --git a/src/devices/cpu/sh/sh4.cpp b/src/devices/cpu/sh/sh4.cpp
index 6e73b69a531..a47754ba4e0 100644
--- a/src/devices/cpu/sh/sh4.cpp
+++ b/src/devices/cpu/sh/sh4.cpp
@@ -26,11 +26,14 @@
#include "emu.h"
#include "sh4.h"
-#include "sh4regs.h"
-#include "sh4comn.h"
+
#include "sh3comn.h"
+#include "sh4fe.h"
+#include "sh4comn.h"
+#include "sh4regs.h"
#include "sh4tmu.h"
#include "sh_dasm.h"
+
#include "cpu/drcumlsh.h"
@@ -937,6 +940,10 @@ sh3_base_device::sh3_base_device(const machine_config &mconfig, device_type type
m_am = SH34_AM;
}
+sh3_base_device::~sh3_base_device()
+{
+}
+
sh4_base_device::sh4_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, endianness_t endianness)
: sh34_base_device(mconfig, type, tag, owner, clock, endianness, address_map_constructor(FUNC(sh4_base_device::sh4_internal_map), this))
@@ -945,6 +952,10 @@ sh4_base_device::sh4_base_device(const machine_config &mconfig, device_type type
m_am = SH34_AM;
}
+sh4_base_device::~sh4_base_device()
+{
+}
+
sh3_device::sh3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, endianness_t endianness)
: sh3_base_device(mconfig, SH3, tag, owner, clock, endianness)
@@ -4231,7 +4242,7 @@ void sh34_base_device::sh4_set_ftcsr_callback(sh4_ftcsr_callback callback)
*/
-const opcode_desc* sh4_base_device::get_desclist(offs_t pc)
+const sh4_base_device::opcode_desc* sh4_base_device::get_desclist(offs_t pc)
{
return m_drcfe->describe_code(pc);
}
@@ -4241,7 +4252,7 @@ void sh4_base_device::init_drc_frontend()
m_drcfe = std::make_unique<sh4_frontend>(this, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, SINGLE_INSTRUCTION_MODE ? 1 : COMPILE_MAX_SEQUENCE);
}
-const opcode_desc* sh3_base_device::get_desclist(offs_t pc)
+const sh3_base_device::opcode_desc* sh3_base_device::get_desclist(offs_t pc)
{
return m_drcfe->describe_code(pc);
}
@@ -4548,7 +4559,7 @@ static void cfunc_STCRBANK(void *param) { ((sh34_base_device *)param)->func_STCR
bool sh34_base_device::generate_group_0_STCRBANK(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_STCRBANK, this);
load_fast_iregs(block);
return true;
@@ -4572,7 +4583,7 @@ static void cfunc_PREFM(void *param) { ((sh34_base_device *)param)->func_PREFM()
bool sh34_base_device::generate_group_0_PREFM(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_PREFM, this);
load_fast_iregs(block);
return true;
@@ -4593,7 +4604,7 @@ static void cfunc_LDTLB(void *param) { ((sh34_base_device *)param)->func_LDTLB()
bool sh34_base_device::generate_group_0_LDTLB(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_LDTLB, this);
load_fast_iregs(block);
return true;
@@ -4605,7 +4616,7 @@ static void cfunc_CLRS(void *param) { ((sh34_base_device *)param)->func_CLRS();
bool sh34_base_device::generate_group_0_CLRS(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_CLRS, this);
load_fast_iregs(block);
return true;
@@ -4617,7 +4628,7 @@ static void cfunc_SETS(void *param) { ((sh34_base_device *)param)->func_SETS();
bool sh34_base_device::generate_group_0_SETS(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_SETS, this);
load_fast_iregs(block);
return true;
@@ -4673,7 +4684,7 @@ static void cfunc_TRAPA(void *param) { ((sh34_base_device *)param)->func_TRAPA()
bool sh34_base_device::generate_group_12_TRAPA(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_MOV(block, mem(&m_sh2_state->pc), desc->pc + 2); // copy the PC because we need to use it
UML_CALLC(block, cfunc_TRAPA, this);
load_fast_iregs(block);
@@ -4687,7 +4698,7 @@ static void cfunc_LDCSR(void *param) { ((sh34_base_device *)param)->func_LDCSR()
bool sh34_base_device::generate_group_4_LDCSR(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_LDCSR, this);
load_fast_iregs(block);
@@ -4702,7 +4713,7 @@ static void cfunc_LDCMSR(void *param) { ((sh34_base_device *)param)->func_LDCMSR
bool sh34_base_device::generate_group_4_LDCMSR(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_LDCMSR, this);
load_fast_iregs(block);
@@ -4719,7 +4730,7 @@ static void cfunc_SHAD(void *param) { ((sh34_base_device *)param)->func_SHAD();
bool sh34_base_device::generate_group_4_SHAD(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_SHAD, this);
load_fast_iregs(block);
return true;
@@ -4731,7 +4742,7 @@ static void cfunc_SHLD(void *param) { ((sh34_base_device *)param)->func_SHLD();
bool sh34_base_device::generate_group_4_SHLD(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_SHLD, this);
load_fast_iregs(block);
return true;
@@ -4867,7 +4878,7 @@ static void cfunc_LDCRBANK(void *param) { ((sh34_base_device *)param)->func_LDCR
bool sh34_base_device::generate_group_4_LDCRBANK(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_LDCRBANK, this);
load_fast_iregs(block);
return true;
@@ -4879,7 +4890,7 @@ static void cfunc_STCMRBANK(void *param) { ((sh34_base_device *)param)->func_STC
bool sh34_base_device::generate_group_4_STCMRBANK(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_STCMRBANK, this);
load_fast_iregs(block);
return true;
@@ -4891,7 +4902,7 @@ static void cfunc_LDCMRBANK(void *param) { ((sh34_base_device *)param)->func_LDC
bool sh34_base_device::generate_group_4_LDCMRBANK(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_LDCMRBANK, this);
load_fast_iregs(block);
return true;
@@ -4903,7 +4914,7 @@ static void cfunc_STCMSGR(void *param) { ((sh34_base_device *)param)->func_STCMS
bool sh34_base_device::generate_group_4_STCMSGR(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_STCMSGR, this);
load_fast_iregs(block);
return true;
@@ -4915,7 +4926,7 @@ static void cfunc_STCMSSR(void *param) { ((sh34_base_device *)param)->func_STCMS
bool sh34_base_device::generate_group_4_STCMSSR(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_STCMSSR, this);
load_fast_iregs(block);
return true;
@@ -4927,7 +4938,7 @@ static void cfunc_LDCMSSR(void *param) { ((sh34_base_device *)param)->func_LDCMS
bool sh34_base_device::generate_group_4_LDCMSSR(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_LDCMSSR, this);
load_fast_iregs(block);
return true;
@@ -4945,7 +4956,7 @@ static void cfunc_STCMSPC(void *param) { ((sh34_base_device *)param)->func_STCMS
bool sh34_base_device::generate_group_4_STCMSPC(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_STCMSPC, this);
load_fast_iregs(block);
return true;
@@ -4957,7 +4968,7 @@ static void cfunc_LDCMSPC(void *param) { ((sh34_base_device *)param)->func_LDCMS
bool sh34_base_device::generate_group_4_LDCMSPC(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_LDCMSPC, this);
load_fast_iregs(block);
return true;
@@ -4975,7 +4986,7 @@ static void cfunc_STSMFPUL(void *param) { ((sh34_base_device *)param)->func_STSM
bool sh34_base_device::generate_group_4_STSMFPUL(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_STSMFPUL, this);
load_fast_iregs(block);
return true;
@@ -4987,7 +4998,7 @@ static void cfunc_LDSMFPUL(void *param) { ((sh34_base_device *)param)->func_LDSM
bool sh34_base_device::generate_group_4_LDSMFPUL(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_LDSMFPUL, this);
load_fast_iregs(block);
return true;
@@ -5005,7 +5016,7 @@ static void cfunc_STSMFPSCR(void *param) { ((sh34_base_device *)param)->func_STS
bool sh34_base_device::generate_group_4_STSMFPSCR(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_STSMFPSCR, this);
load_fast_iregs(block);
return true;
@@ -5018,7 +5029,7 @@ static void cfunc_LDSMFPSCR(void *param) { ((sh34_base_device *)param)->func_LDS
bool sh34_base_device::generate_group_4_LDSMFPSCR(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_LDSMFPSCR, this);
load_fast_iregs(block);
return true;
@@ -5031,7 +5042,7 @@ static void cfunc_LDSFPSCR(void *param) { ((sh34_base_device *)param)->func_LDSF
bool sh34_base_device::generate_group_4_LDSFPSCR(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_LDSFPSCR, this);
load_fast_iregs(block);
return true;
@@ -5043,7 +5054,7 @@ static void cfunc_STCMDBR(void *param) { ((sh34_base_device *)param)->func_STCMD
bool sh34_base_device::generate_group_4_STCMDBR(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_STCMDBR, this);
load_fast_iregs(block);
return true;
@@ -5055,7 +5066,7 @@ static void cfunc_LDCMDBR(void *param) { ((sh34_base_device *)param)->func_LDCMD
bool sh34_base_device::generate_group_4_LDCMDBR(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_LDCMDBR, this);
load_fast_iregs(block);
return true;
@@ -5067,7 +5078,7 @@ static void cfunc_LDCDBR(void *param) { ((sh34_base_device *)param)->func_LDCDBR
bool sh34_base_device::generate_group_4_LDCDBR(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_LDCDBR, this);
load_fast_iregs(block);
return true;
@@ -5211,7 +5222,7 @@ static void cfunc_FMOVS0FR(void *param) { ((sh34_base_device *)param)->func_FMOV
bool sh34_base_device::generate_group_15_FMOVS0FR(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_FMOVS0FR, this);
load_fast_iregs(block);
return true;
@@ -5223,7 +5234,7 @@ static void cfunc_FMOVFRS0(void *param) { ((sh34_base_device *)param)->func_FMOV
bool sh34_base_device::generate_group_15_FMOVFRS0(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_FMOVFRS0, this);
load_fast_iregs(block);
return true;
@@ -5235,7 +5246,7 @@ static void cfunc_FMOVMRFR(void *param) { ((sh34_base_device *)param)->func_FMOV
bool sh34_base_device::generate_group_15_FMOVMRFR(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_FMOVMRFR, this);
load_fast_iregs(block);
return true;
@@ -5247,7 +5258,7 @@ static void cfunc_FMOVMRIFR(void *param) { ((sh34_base_device *)param)->func_FMO
bool sh34_base_device::generate_group_15_FMOVMRIFR(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_FMOVMRIFR, this);
load_fast_iregs(block);
return true;
@@ -5259,7 +5270,7 @@ static void cfunc_FMOVFRMR(void *param) { ((sh34_base_device *)param)->func_FMOV
bool sh34_base_device::generate_group_15_FMOVFRMR(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_FMOVFRMR, this);
load_fast_iregs(block);
return true;
@@ -5271,7 +5282,7 @@ static void cfunc_FMOVFRMDR(void *param) { ((sh34_base_device *)param)->func_FMO
bool sh34_base_device::generate_group_15_FMOVFRMDR(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_FMOVFRMDR, this);
load_fast_iregs(block);
return true;
@@ -5283,7 +5294,7 @@ static void cfunc_FMOVFR(void *param) { ((sh34_base_device *)param)->func_FMOVFR
bool sh34_base_device::generate_group_15_FMOVFR(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_FMOVFR, this);
load_fast_iregs(block);
return true;
@@ -5342,7 +5353,7 @@ static void cfunc_FLDS(void *param) { ((sh34_base_device *)param)->func_FLDS();
bool sh34_base_device::generate_group_15_op1111_0x13_FLDS(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_FLDS, this);
load_fast_iregs(block);
return true;
@@ -5429,7 +5440,7 @@ static void cfunc_FSQRT(void *param) { ((sh34_base_device *)param)->func_FSQRT()
bool sh34_base_device::generate_group_15_op1111_0x13_FSQRT(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_FSQRT, this);
load_fast_iregs(block);
return true;
@@ -5441,7 +5452,7 @@ static void cfunc_FSRRA(void *param) { ((sh34_base_device *)param)->func_FSRRA()
bool sh34_base_device::generate_group_15_op1111_0x13_FSRRA(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_FSRRA, this);
load_fast_iregs(block);
return true;
@@ -5477,7 +5488,7 @@ static void cfunc_FCNVSD(void *param) { ((sh34_base_device *)param)->func_FCNVSD
bool sh34_base_device::generate_group_15_op1111_0x13_FCNVSD(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_FCNVSD, this);
load_fast_iregs(block);
return true;
@@ -5489,7 +5500,7 @@ static void cfunc_FCNVDS(void *param) { ((sh34_base_device *)param)->func_FCNVDS
bool sh34_base_device::generate_group_15_op1111_0x13_FCNVDS(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_FCNVDS, this);
load_fast_iregs(block);
return true;
@@ -5501,7 +5512,7 @@ static void cfunc_FIPR(void *param) { ((sh34_base_device *)param)->func_FIPR();
bool sh34_base_device::generate_group_15_op1111_0x13_FIPR(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_FIPR, this);
load_fast_iregs(block);
return true;
@@ -5572,7 +5583,7 @@ static void cfunc_FTRV(void *param) { ((sh34_base_device *)param)->func_FTRV();
bool sh34_base_device::generate_group_15_op1111_0x13_op1111_0xf13_FTRV(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_FTRV, this);
load_fast_iregs(block);
return true;
@@ -5584,7 +5595,7 @@ static void cfunc_FSSCA(void *param) { ((sh34_base_device *)param)->func_FSSCA()
bool sh34_base_device::generate_group_15_op1111_0x13_op1111_0xf13_FSSCA(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc)
{
save_fast_iregs(block);
- UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr);
UML_CALLC(block, cfunc_FSSCA, this);
load_fast_iregs(block);
return true;
diff --git a/src/devices/cpu/sh/sh4.h b/src/devices/cpu/sh/sh4.h
index c4fc1c0cd1c..d92e374bc5e 100644
--- a/src/devices/cpu/sh/sh4.h
+++ b/src/devices/cpu/sh/sh4.h
@@ -155,8 +155,6 @@ struct sh4_utlb
typedef void (*sh4_ftcsr_callback)(uint32_t);
-class sh4_frontend;
-
class sh34_base_device : public sh_common_execution
{
public:
@@ -250,6 +248,8 @@ public:
void func_STCSPC();
protected:
+ class sh4_frontend;
+
// construction/destruction
sh34_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, endianness_t endianness, address_map_constructor internal);
@@ -684,7 +684,8 @@ private:
class sh3_base_device : public sh34_base_device
{
- friend class sh4_frontend;
+public:
+ virtual ~sh3_base_device();
protected:
// construction/destruction
@@ -1234,9 +1235,10 @@ protected:
class sh4_base_device : public sh34_base_device
{
-protected:
- friend class sh4_frontend;
+public:
+ virtual ~sh4_base_device();
+protected:
// construction/destruction
sh4_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, endianness_t endianness);
@@ -1972,32 +1974,18 @@ protected:
virtual void sh4_register_map(address_map& map) override ATTR_COLD;
};
-class sh4_frontend : public sh_frontend
-{
-public:
- sh4_frontend(sh_common_execution *device, uint32_t window_start, uint32_t window_end, uint32_t max_sequence);
-
-protected:
- virtual uint16_t read_word(opcode_desc &desc) override;
-private:
- virtual bool describe_group_0(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode) override;
- virtual bool describe_group_4(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode) override;
- virtual bool describe_group_15(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode) override;
- bool describe_op1111_0x13(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode);
- bool describe_op1111_0xf13(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode);
-};
-
-DECLARE_DEVICE_TYPE(SH3, sh3_device)
+DECLARE_DEVICE_TYPE(SH3, sh3_device)
DECLARE_DEVICE_TYPE(SH7708S, sh7708s_device)
-DECLARE_DEVICE_TYPE(SH7709, sh7709_device)
+DECLARE_DEVICE_TYPE(SH7709, sh7709_device)
DECLARE_DEVICE_TYPE(SH7709S, sh7709s_device)
-DECLARE_DEVICE_TYPE(SH4, sh4_device)
-DECLARE_DEVICE_TYPE(SH7091, sh7091_device)
-DECLARE_DEVICE_TYPE(SH7750, sh7750_device)
+
+DECLARE_DEVICE_TYPE(SH4, sh4_device)
+DECLARE_DEVICE_TYPE(SH7091, sh7091_device)
+DECLARE_DEVICE_TYPE(SH7750, sh7750_device)
DECLARE_DEVICE_TYPE(SH7750R, sh7750r_device)
DECLARE_DEVICE_TYPE(SH7750S, sh7750s_device)
-DECLARE_DEVICE_TYPE(SH7751, sh7751_device)
+DECLARE_DEVICE_TYPE(SH7751, sh7751_device)
DECLARE_DEVICE_TYPE(SH7751R, sh7751r_device)
#endif // MAME_CPU_SH_SH4_H
diff --git a/src/devices/cpu/sh/sh4comn.h b/src/devices/cpu/sh/sh4comn.h
index bac004d36b4..00eab9bf51c 100644
--- a/src/devices/cpu/sh/sh4comn.h
+++ b/src/devices/cpu/sh/sh4comn.h
@@ -63,8 +63,6 @@ enum
#define SZ 0x00100000
#define FR 0x00200000
-#define REGFLAG_R(n) (1 << (n))
-
/* additional register flags 1 */
#define REGFLAG_SGR (1 << 6)
#define REGFLAG_FPUL (1 << 7)
diff --git a/src/devices/cpu/sh/sh4fe.cpp b/src/devices/cpu/sh/sh4fe.cpp
index 8474cb48171..d05bd07751f 100644
--- a/src/devices/cpu/sh/sh4fe.cpp
+++ b/src/devices/cpu/sh/sh4fe.cpp
@@ -9,21 +9,23 @@
***************************************************************************/
#include "emu.h"
-#include "sh4.h"
+#include "sh4fe.h"
+
#include "sh4comn.h"
-#include "cpu/drcfe.h"
+
+// FIXME: if the code generation is to be improved, this needs to actually describe the instructions
/***************************************************************************
INSTRUCTION PARSERS
***************************************************************************/
-sh4_frontend::sh4_frontend(sh_common_execution *device, uint32_t window_start, uint32_t window_end, uint32_t max_sequence)
- : sh_frontend(device, window_start, window_end, max_sequence)
+sh34_base_device::sh4_frontend::sh4_frontend(sh_common_execution *device, uint32_t window_start, uint32_t window_end, uint32_t max_sequence)
+ : frontend(device, window_start, window_end, max_sequence)
{
}
-uint16_t sh4_frontend::read_word(opcode_desc &desc)
+uint16_t sh34_base_device::sh4_frontend::read_word(opcode_desc &desc)
{
if (desc.physpc >= 0xe0000000)
return m_sh->m_pr16(desc.physpc);
@@ -33,13 +35,13 @@ uint16_t sh4_frontend::read_word(opcode_desc &desc)
}
-bool sh4_frontend::describe_group_0(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode)
+bool sh34_base_device::sh4_frontend::describe_group_0(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode)
{
switch (opcode & 0xff)
{
default:
// fall through to SH2 handlers
- return sh_frontend::describe_group_0(desc, prev, opcode);
+ return frontend::describe_group_0(desc, prev, opcode);
case 0x52:
case 0x62:
@@ -105,14 +107,14 @@ bool sh4_frontend::describe_group_0(opcode_desc &desc, const opcode_desc *prev,
}
-bool sh4_frontend::describe_group_4(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode)
+bool sh34_base_device::sh4_frontend::describe_group_4(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode)
{
switch (opcode & 0xff)
{
default: // LDCMSR (0x0e) has sh2/4 flag difference
// fall through to SH2 handlers
- return sh_frontend::describe_group_4(desc, prev, opcode);
+ return frontend::describe_group_4(desc, prev, opcode);
case 0x42:
case 0x46:
@@ -231,7 +233,7 @@ bool sh4_frontend::describe_group_4(opcode_desc &desc, const opcode_desc *prev,
}
// SH4 only (FPU ops)
-bool sh4_frontend::describe_group_15(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode)
+bool sh34_base_device::sh4_frontend::describe_group_15(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode)
{
switch (opcode & 0x0f)
{
@@ -258,7 +260,7 @@ bool sh4_frontend::describe_group_15(opcode_desc &desc, const opcode_desc *prev,
return false;
}
-bool sh4_frontend::describe_op1111_0x13(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode)
+bool sh34_base_device::sh4_frontend::describe_op1111_0x13(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode)
{
switch ((opcode >> 4) & 0x0f)
{
@@ -282,7 +284,7 @@ bool sh4_frontend::describe_op1111_0x13(opcode_desc &desc, const opcode_desc *pr
return false;
}
-bool sh4_frontend::describe_op1111_0xf13(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode)
+bool sh34_base_device::sh4_frontend::describe_op1111_0xf13(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode)
{
if (opcode & 0x100)
{
diff --git a/src/devices/cpu/sh/sh4fe.h b/src/devices/cpu/sh/sh4fe.h
new file mode 100644
index 00000000000..f3ce57bf74a
--- /dev/null
+++ b/src/devices/cpu/sh/sh4fe.h
@@ -0,0 +1,36 @@
+// license:BSD-3-Clause
+// copyright-holders:R. Belmont
+/***************************************************************************
+
+ sh4fe.h
+
+ Front end for SH-4 recompiler
+
+***************************************************************************/
+#ifndef MAME_CPU_SH_SH4FE_H
+#define MAME_CPU_SH_SH4FE_H
+
+#pragma once
+
+#include "sh4.h"
+#include "sh_fe.h"
+
+
+class sh34_base_device::sh4_frontend : public sh_common_execution::frontend
+{
+public:
+ sh4_frontend(sh_common_execution *device, uint32_t window_start, uint32_t window_end, uint32_t max_sequence);
+
+protected:
+ virtual uint16_t read_word(opcode_desc &desc) override;
+
+ virtual bool describe_group_0(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode) override;
+ virtual bool describe_group_4(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode) override;
+ virtual bool describe_group_15(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode) override;
+
+private:
+ bool describe_op1111_0x13(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode);
+ bool describe_op1111_0xf13(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode);
+};
+
+#endif // MAME_CPU_SH_SH4FE_H
diff --git a/src/devices/cpu/sh/sh_fe.cpp b/src/devices/cpu/sh/sh_fe.cpp
index 5e803b8ee00..f62ecf110fb 100644
--- a/src/devices/cpu/sh/sh_fe.cpp
+++ b/src/devices/cpu/sh/sh_fe.cpp
@@ -4,41 +4,52 @@
sh_fe.cpp
- Front end for SH recompiler
+ Front end for SuperH recompiler
***************************************************************************/
#include "emu.h"
-#include "sh2.h"
-#include "cpu/drcfe.h"
+#include "sh_fe.h"
+
+#include "cpu/drcfe.ipp"
/***************************************************************************
INSTRUCTION PARSERS
***************************************************************************/
-sh_frontend::sh_frontend(sh_common_execution *device, uint32_t window_start, uint32_t window_end, uint32_t max_sequence)
- : drc_frontend(*device, window_start, window_end, max_sequence)
+sh_common_execution::frontend::frontend(sh_common_execution *device, uint32_t window_start, uint32_t window_end, uint32_t max_sequence)
+ : drc_frontend_base(device->space_config(AS_PROGRAM)->page_shift(), window_start, window_end, max_sequence)
, m_sh(device)
{
}
-/*-------------------------------------------------
- describe_instruction - build a description
- of a single instruction
--------------------------------------------------*/
+sh_common_execution::frontend::~frontend()
+{
+}
-inline uint16_t sh_frontend::read_word(opcode_desc &desc)
+sh_common_execution::opcode_desc const *sh_common_execution::frontend::describe_code(offs_t startpc)
{
- return m_sh->m_pr16(desc.physpc);
+ return do_describe_code(
+ [this] (opcode_desc &desc, opcode_desc const *prev) { return describe(desc, prev); },
+ startpc);
}
-bool sh_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
+
+inline uint16_t sh_common_execution::frontend::read_word(opcode_desc &desc)
{
- uint16_t opcode;
+ return m_sh->m_pr16(desc.physpc);
+}
+
+/*-------------------------------------------------
+ describe_instruction - build a description
+ of a single instruction
+-------------------------------------------------*/
+bool sh_common_execution::frontend::describe(opcode_desc &desc, const opcode_desc *prev)
+{
/* fetch the opcode */
- opcode = desc.opptr.w[0] = read_word(desc);
+ const uint16_t opcode = desc.opptr = read_word(desc);
/* all instructions are 2 bytes and most are a single cycle */
desc.length = 2;
@@ -46,88 +57,91 @@ bool sh_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
switch (opcode>>12)
{
- case 0:
- return describe_group_0(desc, prev, opcode);
+ case 0:
+ return describe_group_0(desc, prev, opcode);
- case 1: // MOVLS4
- desc.regin[0] |= REGFLAG_R(REG_N) | REGFLAG_R(REG_M);
- desc.flags |= OPFLAG_WRITES_MEMORY;
- return true;
+ case 1: // MOVLS4
+ desc.set_r_used(REG_M);
+ desc.set_r_used(REG_N);
+ desc.set_writes_memory();
+ return true;
- case 2:
- return describe_group_2(desc, prev, opcode);
+ case 2:
+ return describe_group_2(desc, prev, opcode);
- case 3:
- return describe_group_3(desc, prev, opcode);
+ case 3:
+ return describe_group_3(desc, prev, opcode);
- case 4:
- return describe_group_4(desc, prev, opcode);
+ case 4:
+ return describe_group_4(desc, prev, opcode);
- case 5: // MOVLL4
- desc.regin[0] |= REGFLAG_R(REG_M);
- desc.regout[0] |= REGFLAG_R(REG_N);
- desc.flags |= OPFLAG_READS_MEMORY;
- return true;
+ case 5: // MOVLL4
+ desc.set_r_used(REG_M);
+ desc.set_r_modified(REG_N);
+ desc.set_reads_memory();
+ return true;
- case 6:
- return describe_group_6(desc, prev, opcode);
+ case 6:
+ return describe_group_6(desc, prev, opcode);
- case 7: // ADDI
- desc.regin[0] |= REGFLAG_R(REG_N);
- desc.regout[0] |= REGFLAG_R(REG_N);
- return true;
+ case 7: // ADDI
+ desc.set_r_used(REG_N);
+ desc.set_r_modified(REG_N);
+ return true;
- case 8:
- return describe_group_8(desc, prev, opcode);
+ case 8:
+ return describe_group_8(desc, prev, opcode);
- case 9: // MOVWI
- desc.regout[0] |= REGFLAG_R(REG_N);
- desc.flags |= OPFLAG_READS_MEMORY;
- return true;
+ case 9: // MOVWI
+ desc.set_r_modified(REG_N);
+ desc.set_reads_memory();
+ return true;
- case 11: // BSR
- desc.regout[1] |= REGFLAG_PR;
- [[fallthrough]]; // BSR is BRA with the addition of PR = the return address
- case 10: // BRA
- {
- int32_t disp = util::sext(opcode, 12);
-
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
- desc.targetpc = (desc.pc + 2) + disp * 2 + 2;
- desc.delayslots = 1;
- desc.cycles = 2;
- return true;
- }
-
- case 12:
- return describe_group_12(desc, prev, opcode);
-
- case 13: // MOVLI
- desc.regout[0] |= REGFLAG_R(REG_N);
- desc.flags |= OPFLAG_READS_MEMORY;
- return true;
+ case 11: // BSR
+ desc.set_pr_modified();
+ [[fallthrough]]; // BSR is BRA with the addition of PR = the return address
+ case 10: // BRA
+ {
+ int32_t disp = util::sext(opcode, 12);
- case 14: // MOVI
- desc.regout[0] |= REGFLAG_R(REG_N);
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
+ desc.targetpc = (desc.pc + 2) + disp * 2 + 2;
+ desc.delayslots = 1;
+ desc.cycles = 2;
return true;
+ }
+
+ case 12:
+ return describe_group_12(desc, prev, opcode);
+
+ case 13: // MOVLI
+ desc.set_r_modified(REG_N);
+ desc.set_reads_memory();
+ return true;
+
+ case 14: // MOVI
+ desc.set_r_modified(REG_N);
+ return true;
- case 15: // NOP
- return describe_group_15(desc, prev, opcode);
+ case 15: // NOP
+ return describe_group_15(desc, prev, opcode);
}
return false;
}
-bool sh_frontend::describe_group_2(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode)
+bool sh_common_execution::frontend::describe_group_2(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode)
{
switch (opcode & 15)
{
case 0: // MOVBS(Rm, Rn);
case 1: // MOVWS(Rm, Rn);
case 2: // MOVLS(Rm, Rn);
- desc.regin[0] |= REGFLAG_R(REG_M) | REGFLAG_R(REG_N);
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_r_used(REG_M);
+ desc.set_r_used(REG_N);
+ desc.set_writes_memory();
return true;
case 3: // NOP();
@@ -137,29 +151,33 @@ bool sh_frontend::describe_group_2(opcode_desc &desc, const opcode_desc *prev, u
case 5: // MOVWM(Rm, Rn);
case 6: // MOVLM(Rm, Rn);
case 13: // XTRCT(Rm, Rn);
- desc.regin[0] |= REGFLAG_R(REG_M) | REGFLAG_R(REG_N);
- desc.regout[0] |= REGFLAG_R(REG_N);
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_r_used(REG_M);
+ desc.set_r_used(REG_N);
+ desc.set_r_modified(REG_N);
+ desc.set_writes_memory();
return true;
case 7: // DIV0S(Rm, Rn);
case 8: // TST(Rm, Rn);
case 12: // CMPSTR(Rm, Rn);
- desc.regin[0] |= REGFLAG_R(REG_M) | REGFLAG_R(REG_N);
- desc.regout[1] |= REGFLAG_SR;
+ desc.set_r_used(REG_M);
+ desc.set_r_used(REG_N);
+ desc.set_sr_modified();
return true;
case 9: // AND(Rm, Rn);
case 10: // XOR(Rm, Rn);
case 11: // OR(Rm, Rn);
- desc.regin[0] |= REGFLAG_R(REG_M) | REGFLAG_R(REG_N);
- desc.regout[0] |= REGFLAG_R(REG_N);
+ desc.set_r_used(REG_M);
+ desc.set_r_used(REG_N);
+ desc.set_r_modified(REG_N);
return true;
case 14: // MULU(Rm, Rn);
case 15: // MULS(Rm, Rn);
- desc.regin[0] |= REGFLAG_R(REG_M) | REGFLAG_R(REG_N);
- desc.regout[1] |= REGFLAG_MACL | REGFLAG_MACH;
+ desc.set_r_used(REG_M);
+ desc.set_r_used(REG_N);
+ desc.set_mac_modified();
desc.cycles = 2;
return true;
}
@@ -167,7 +185,7 @@ bool sh_frontend::describe_group_2(opcode_desc &desc, const opcode_desc *prev, u
return false;
}
-bool sh_frontend::describe_group_3(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode)
+bool sh_common_execution::frontend::describe_group_3(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode)
{
switch (opcode & 15)
{
@@ -176,8 +194,9 @@ bool sh_frontend::describe_group_3(opcode_desc &desc, const opcode_desc *prev, u
case 3: // CMPGE(Rm, Rn);
case 6: // CMPHI(Rm, Rn);
case 7: // CMPGT(Rm, Rn);
- desc.regin[0] |= REGFLAG_R(REG_M) | REGFLAG_R(REG_N);
- desc.regout[1] |= REGFLAG_SR;
+ desc.set_r_used(REG_M);
+ desc.set_r_used(REG_N);
+ desc.set_sr_modified();
return true;
case 1: // NOP();
@@ -185,39 +204,43 @@ bool sh_frontend::describe_group_3(opcode_desc &desc, const opcode_desc *prev, u
return true;
case 4: // DIV1(Rm, Rn);
- desc.regin[0] |= REGFLAG_R(REG_M) | REGFLAG_R(REG_N);
- desc.regout[0] |= REGFLAG_R(REG_N);
- desc.regout[1] |= REGFLAG_SR;
+ desc.set_r_used(REG_M);
+ desc.set_r_used(REG_N);
+ desc.set_r_modified(REG_N);
+ desc.set_sr_modified();
return true;
case 5: // DMULU(Rm, Rn);
case 13: // DMULS(Rm, Rn);
- desc.regin[0] |= REGFLAG_R(REG_M) | REGFLAG_R(REG_N);
- desc.regout[1] |= REGFLAG_MACL | REGFLAG_MACH;
+ desc.set_r_used(REG_M);
+ desc.set_r_used(REG_N);
+ desc.set_mac_modified();
desc.cycles = 2;
return true;
case 8: // SUB(Rm, Rn);
case 12: // ADD(Rm, Rn);
- desc.regin[0] |= REGFLAG_R(REG_M) | REGFLAG_R(REG_N);
- desc.regout[0] |= REGFLAG_R(REG_N);
+ desc.set_r_used(REG_M);
+ desc.set_r_used(REG_N);
+ desc.set_r_modified(REG_N);
return true;
case 10: // SUBC(Rm, Rn);
case 11: // SUBV(Rm, Rn);
case 14: // ADDC(Rm, Rn);
case 15: // ADDV(Rm, Rn);
- desc.regin[0] |= REGFLAG_R(REG_M) | REGFLAG_R(REG_N);
- desc.regin[1] |= REGFLAG_SR;
- desc.regout[0] |= REGFLAG_R(REG_N);
- desc.regout[1] |= REGFLAG_SR;
+ desc.set_r_used(REG_M);
+ desc.set_r_used(REG_N);
+ desc.set_sr_used();
+ desc.set_r_modified(REG_N);
+ desc.set_sr_modified();
return true;
}
return false;
}
-bool sh_frontend::describe_group_6(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode)
+bool sh_common_execution::frontend::describe_group_6(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode)
{
switch (opcode & 15)
{
@@ -232,33 +255,35 @@ bool sh_frontend::describe_group_6(opcode_desc &desc, const opcode_desc *prev, u
case 13: // EXTUW(Rm, Rn);
case 14: // EXTSB(Rm, Rn);
case 15: // EXTSW(Rm, Rn);
- desc.regin[0] |= REGFLAG_R(REG_M);
- desc.regout[0] |= REGFLAG_R(REG_N);
+ desc.set_r_used(REG_M);
+ desc.set_r_modified(REG_N);
return true;
case 4: // MOVBP(Rm, Rn);
case 5: // MOVWP(Rm, Rn);
case 6: // MOVLP(Rm, Rn);
- desc.regin[0] |= REGFLAG_R(REG_M) | REGFLAG_R(REG_N);
- desc.regout[0] |= REGFLAG_R(REG_N);
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_r_used(REG_M);
+ desc.set_r_used(REG_N);
+ desc.set_r_modified(REG_N);
+ desc.set_reads_memory();
return true;
case 8: // SWAPB(Rm, Rn);
- desc.regin[0] |= REGFLAG_R(REG_M) | REGFLAG_R(REG_N);
- desc.regout[0] |= REGFLAG_R(REG_N);
+ desc.set_r_used(REG_M);
+ desc.set_r_used(REG_N);
+ desc.set_r_modified(REG_N);
return true;
case 10: // NEGC(Rm, Rn);
- desc.regin[0] |= REGFLAG_R(REG_M);
- desc.regout[0] |= REGFLAG_R(REG_N);
- desc.regout[1] |= REGFLAG_SR;
+ desc.set_r_used(REG_M);
+ desc.set_r_modified(REG_N);
+ desc.set_sr_modified();
return true;
}
return false;
}
-bool sh_frontend::describe_group_8(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode)
+bool sh_common_execution::frontend::describe_group_8(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode)
{
int32_t disp;
@@ -266,8 +291,9 @@ bool sh_frontend::describe_group_8(opcode_desc &desc, const opcode_desc *prev, u
{
case 0 << 8: // MOVBS4(opcode & 0x0f, Rm);
case 1 << 8: // MOVWS4(opcode & 0x0f, Rm);
- desc.regin[0] |= REGFLAG_R(REG_M) | REGFLAG_R(0);
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_r_used(REG_M);
+ desc.set_r_used(0);
+ desc.set_writes_memory();
return true;
case 2 << 8: // NOP();
@@ -281,20 +307,20 @@ bool sh_frontend::describe_group_8(opcode_desc &desc, const opcode_desc *prev, u
case 4 << 8: // MOVBL4(Rm, opcode & 0x0f);
case 5 << 8: // MOVWL4(Rm, opcode & 0x0f);
- desc.regin[0] |= REGFLAG_R(REG_M);
- desc.regout[0] |= REGFLAG_R(0);
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_r_used(REG_M);
+ desc.set_r_modified(0);
+ desc.set_reads_memory();
return true;
case 8 << 8: // CMPIM(opcode & 0xff);
- desc.regin[0] |= REGFLAG_R(REG_M);
- desc.regin[1] |= REGFLAG_SR;
- desc.regout[1] |= REGFLAG_SR;
+ desc.set_r_used(REG_M);
+ desc.set_sr_used();
+ desc.set_sr_modified();
return true;
case 9 << 8: // BT(opcode & 0xff);
case 11 << 8: // BF(opcode & 0xff);
- desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+ desc.set_is_conditional_branch();
desc.cycles = 3;
disp = util::sext(opcode, 8);
desc.targetpc = (desc.pc + 2) + disp * 2 + 2;
@@ -302,7 +328,7 @@ bool sh_frontend::describe_group_8(opcode_desc &desc, const opcode_desc *prev, u
case 13 << 8: // BTS(opcode & 0xff);
case 15 << 8: // BFS(opcode & 0xff);
- desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+ desc.set_is_conditional_branch();
desc.cycles = 2;
disp = util::sext(opcode, 8);
desc.targetpc = (desc.pc + 2) + disp * 2 + 2;
@@ -313,55 +339,58 @@ bool sh_frontend::describe_group_8(opcode_desc &desc, const opcode_desc *prev, u
return false;
}
-bool sh_frontend::describe_group_12(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode)
+bool sh_common_execution::frontend::describe_group_12(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode)
{
switch (opcode & (15<<8))
{
case 0 << 8: // MOVBSG(opcode & 0xff);
case 1 << 8: // MOVWSG(opcode & 0xff);
case 2 << 8: // MOVLSG(opcode & 0xff);
- desc.regin[0] |= REGFLAG_R(0);
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_r_used(0);
+ desc.set_writes_memory();
return true;
case 3 << 8: // TRAPA(opcode & 0xff);
- desc.regin[0] |= REGFLAG_R(15);
- desc.regin[1] |= REGFLAG_VBR;
- desc.regout[0] |= REGFLAG_R(15);
+ desc.set_r_used(15);
+ desc.set_vbr_used();
+ desc.set_r_modified(15);
desc.cycles = 8;
desc.targetpc = BRANCH_TARGET_DYNAMIC;
- desc.flags |= OPFLAG_READS_MEMORY | OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
+ desc.set_reads_memory();
return true;
case 4 << 8: // MOVBLG(opcode & 0xff);
case 5 << 8: // MOVWLG(opcode & 0xff);
case 6 << 8: // MOVLLG(opcode & 0xff);
case 7 << 8: // MOVA(opcode & 0xff);
- desc.regout[0] |= REGFLAG_R(0);
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_r_modified(0);
+ desc.set_reads_memory();
return true;
case 8 << 8: // TSTI(opcode & 0xff);
- desc.regin[0] |= REGFLAG_R(0);
- desc.regin[1] |= REGFLAG_SR;
- desc.regout[1] |= REGFLAG_SR;
+ desc.set_r_used(0);
+ desc.set_sr_used();
+ desc.set_sr_modified();
return true;
case 9 << 8: // ANDI(opcode & 0xff);
case 10 << 8: // XORI(opcode & 0xff);
case 11 << 8: // ORI(opcode & 0xff);
- desc.regin[0] |= REGFLAG_R(0);
- desc.regout[0] |= REGFLAG_R(0);
+ desc.set_r_used(0);
+ desc.set_r_modified(0);
return true;
case 12 << 8: // TSTM(opcode & 0xff);
case 13 << 8: // ANDM(opcode & 0xff);
case 14 << 8: // XORM(opcode & 0xff);
case 15 << 8: // ORM(opcode & 0xff);
- desc.regin[0] |= REGFLAG_R(0);
- desc.regin[1] |= REGFLAG_SR | REGFLAG_GBR;
- desc.regout[1] |= REGFLAG_SR;
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_r_used(0);
+ desc.set_sr_used();
+ desc.set_gbr_used();
+ desc.set_sr_modified();
+ desc.set_reads_memory();
return true;
}
@@ -370,9 +399,9 @@ bool sh_frontend::describe_group_12(opcode_desc &desc, const opcode_desc *prev,
-bool sh_frontend::describe_group_0(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode)
+bool sh_common_execution::frontend::describe_group_0(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode)
{
- switch (opcode & 0x3F)
+ switch (opcode & 0x3f)
{
case 0x00: // NOP();
case 0x01: // NOP();
@@ -393,13 +422,14 @@ bool sh_frontend::describe_group_0(opcode_desc &desc, const opcode_desc *prev, u
return true;
case 0x02: // STCSR(Rn);
- desc.regout[0] |= REGFLAG_R(REG_N);
+ desc.set_r_modified(REG_N);
return true;
case 0x03: // BSRF(Rn);
- desc.regout[1] |= REGFLAG_PR;
+ desc.set_pr_modified();
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
desc.targetpc = BRANCH_TARGET_DYNAMIC;
desc.delayslots = 1;
@@ -417,32 +447,36 @@ bool sh_frontend::describe_group_0(opcode_desc &desc, const opcode_desc *prev, u
case 0x34: // MOVBS0(Rm, Rn);
case 0x35: // MOVWS0(Rm, Rn);
case 0x36: // MOVLS0(Rm, Rn);
- desc.regin[0] |= REGFLAG_R(REG_M) | REGFLAG_R(REG_N) | REGFLAG_R(0);
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_r_used(REG_M);
+ desc.set_r_used(REG_N);
+ desc.set_r_used(0);
+ desc.set_writes_memory();
return true;
case 0x07: // MULL(Rm, Rn);
case 0x17: // MULL(Rm, Rn);
case 0x27: // MULL(Rm, Rn);
case 0x37: // MULL(Rm, Rn);
- desc.regin[0] |= REGFLAG_R(REG_N) | REGFLAG_R(REG_M);
- desc.regout[1] |= REGFLAG_MACL;
+ desc.set_r_used(REG_M);
+ desc.set_r_used(REG_N);
+ desc.set_macl_modified();
desc.cycles = 2;
return true;
case 0x08: // CLRT();
- desc.regout[1] |= REGFLAG_SR;
+ desc.set_sr_modified();
return true;
case 0x0a: // STSMACH(Rn);
- desc.regout[0] |= REGFLAG_R(REG_N);
- desc.regout[1] |= REGFLAG_MACH;
+ desc.set_r_modified(REG_N);
+ desc.set_mach_modified();
return true;
case 0x0b: // RTS();
- desc.regin[1] |= REGFLAG_PR;
+ desc.set_pr_used();
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
desc.targetpc = BRANCH_TARGET_DYNAMIC;
desc.delayslots = 1;
desc.cycles = 2;
@@ -461,36 +495,38 @@ bool sh_frontend::describe_group_0(opcode_desc &desc, const opcode_desc *prev, u
case 0x3c: // MOVBL0(Rm, Rn);
case 0x3d: // MOVWL0(Rm, Rn);
case 0x3e: // MOVLL0(Rm, Rn);
- desc.regin[0] |= REGFLAG_R(REG_M) | REGFLAG_R(0);
- desc.regout[0] |= REGFLAG_R(REG_N);
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_r_used(REG_M);
+ desc.set_r_used(0);
+ desc.set_r_modified(REG_N);
+ desc.set_reads_memory();
return true;
case 0x0f: // MAC_L(Rm, Rn);
case 0x1f: // MAC_L(Rm, Rn);
case 0x2f: // MAC_L(Rm, Rn);
case 0x3f: // MAC_L(Rm, Rn);
- desc.regin[0] |= REGFLAG_R(REG_M) | REGFLAG_R(REG_N);
- desc.regout[1] |= REGFLAG_MACL | REGFLAG_MACH;
+ desc.set_r_used(REG_M);
+ desc.set_r_used(REG_N);
+ desc.set_mac_modified();
desc.cycles = 3;
return true;
case 0x12: // STCGBR(Rn);
- desc.regout[0] |= REGFLAG_R(REG_N);
- desc.regin[1] |= REGFLAG_GBR;
+ desc.set_r_modified(REG_N);
+ desc.set_gbr_used();
return true;
case 0x18: // SETT();
- desc.regout[1] |= REGFLAG_SR;
+ desc.set_sr_modified();
return true;
case 0x19: // DIV0U();
- desc.regout[1] |= REGFLAG_SR;
+ desc.set_sr_modified();
return true;
case 0x1a: // STSMACL(Rn);
- desc.regin[1] |= REGFLAG_MACL;
- desc.regout[0] |= REGFLAG_R(REG_N);
+ desc.set_macl_used();
+ desc.set_r_modified(REG_N);
return true;
case 0x1b: // SLEEP();
@@ -498,37 +534,40 @@ bool sh_frontend::describe_group_0(opcode_desc &desc, const opcode_desc *prev, u
return true;
case 0x22: // STCVBR(Rn);
- desc.regin[0] |= REGFLAG_R(REG_N);
- desc.regout[1] |= REGFLAG_VBR;
+ desc.set_r_used(REG_N);
+ desc.set_vbr_modified();
return true;
case 0x23: // BRAF(Rn);
- desc.regin[0] |= REGFLAG_R(REG_M);
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.set_r_used(REG_M);
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
desc.targetpc = BRANCH_TARGET_DYNAMIC;
desc.delayslots = 1;
desc.cycles = 2;
return true;
case 0x28: // CLRMAC();
- desc.regout[1] |= REGFLAG_MACL | REGFLAG_MACH;
+ desc.set_mac_modified();
return true;
case 0x29: // MOVT(Rn);
- desc.regin[1] |= REGFLAG_SR;
- desc.regout[0] |= REGFLAG_R(REG_N);
+ desc.set_sr_used();
+ desc.set_r_modified(REG_N);
return true;
case 0x2a: // STSPR(Rn);
- desc.regin[1] |= REGFLAG_PR;
- desc.regout[0] |= REGFLAG_R(REG_N);
+ desc.set_pr_used();
+ desc.set_r_modified(REG_N);
return true;
case 0x2b: // RTE();
- desc.regin[0] |= REGFLAG_R(15);
- desc.regout[0] |= REGFLAG_R(15);
+ desc.set_r_used(15);
+ desc.set_r_modified(15);
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE | OPFLAG_CAN_EXPOSE_EXTERNAL_INT;
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
+ desc.set_can_expose_external_int();
desc.targetpc = BRANCH_TARGET_DYNAMIC;
desc.delayslots = 1;
desc.cycles = 4;
@@ -540,7 +579,7 @@ bool sh_frontend::describe_group_0(opcode_desc &desc, const opcode_desc *prev, u
}
-bool sh_frontend::describe_group_4(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode)
+bool sh_common_execution::frontend::describe_group_4(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode)
{
switch (opcode & 0x3F)
{
@@ -548,38 +587,40 @@ bool sh_frontend::describe_group_4(opcode_desc &desc, const opcode_desc *prev, u
case 0x01: // SHLR(Rn);
case 0x04: // ROTL(Rn);
case 0x05: // ROTR(Rn);
- desc.regin[0] |= REGFLAG_R(REG_N);
- desc.regout[0] |= REGFLAG_R(REG_N);
- desc.regout[1] |= REGFLAG_SR;
+ desc.set_r_used(REG_N);
+ desc.set_r_modified(REG_N);
+ desc.set_sr_modified();
return true;
case 0x02: // STSMMACH(Rn);
- desc.regin[0] |= REGFLAG_R(REG_N);
- desc.regin[1] |= REGFLAG_MACH;
- desc.regout[0] |= REGFLAG_R(REG_N);
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_r_used(REG_N);
+ desc.set_mach_used();
+ desc.set_r_modified(REG_N);
+ desc.set_writes_memory();
return true;
case 0x03: // STCMSR(Rn);
- desc.regin[0] |= REGFLAG_R(REG_N);
- desc.regout[0] |= REGFLAG_R(REG_N);
+ desc.set_r_used(REG_N);
+ desc.set_r_modified(REG_N);
desc.cycles = 2;
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_writes_memory();
return true;
case 0x06: // LDSMMACH(Rn);
- desc.regin[0] |= REGFLAG_R(REG_N);
- desc.regout[0] |= REGFLAG_R(REG_N);
- desc.regout[1] |= REGFLAG_MACH;
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_r_used(REG_N);
+ desc.set_r_modified(REG_N);
+ desc.set_mach_modified();
+ desc.set_reads_memory();
return true;
case 0x07: // LDCMSR(Rn);
- desc.regin[0] |= REGFLAG_R(REG_N);
- desc.regout[0] |= REGFLAG_R(REG_N);
- desc.regout[1] |= REGFLAG_SR;
+ desc.set_r_used(REG_N);
+ desc.set_r_modified(REG_N);
+ desc.set_sr_modified();
desc.cycles = 3;
- desc.flags |= OPFLAG_READS_MEMORY | OPFLAG_CAN_EXPOSE_EXTERNAL_INT | OPFLAG_END_SEQUENCE;
+ desc.set_end_sequence();
+ desc.set_reads_memory();
+ desc.set_can_expose_external_int();
return true;
case 0x08: // SHLL2(Rn);
@@ -588,158 +629,166 @@ bool sh_frontend::describe_group_4(opcode_desc &desc, const opcode_desc *prev, u
case 0x19: // SHLR8(Rn);
case 0x28: // SHLL16(Rn);
case 0x29: // SHLR16(Rn);
- desc.regin[0] |= REGFLAG_R(REG_N);
- desc.regout[0] |= REGFLAG_R(REG_N);
+ desc.set_r_used(REG_N);
+ desc.set_r_modified(REG_N);
return true;
case 0x0a: // LDSMACH(Rn);
- desc.regin[0] |= REGFLAG_R(REG_N);
- desc.regout[1] |= REGFLAG_MACH;
+ desc.set_r_used(REG_N);
+ desc.set_mach_modified();
return true;
case 0x0b: // JSR(Rn);
- desc.regin[0] |= REGFLAG_R(REG_N);
- desc.regout[1] |= REGFLAG_PR;
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.set_r_used(REG_N);
+ desc.set_pr_modified();
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
desc.targetpc = BRANCH_TARGET_DYNAMIC;
desc.delayslots = 1;
return true;
case 0x0e: // LDCSR(Rn);
- desc.regin[0] |= REGFLAG_R(REG_N);
- desc.regout[1] |= REGFLAG_SR;
- desc.flags |= OPFLAG_CAN_EXPOSE_EXTERNAL_INT | OPFLAG_END_SEQUENCE;
+ desc.set_r_used(REG_N);
+ desc.set_sr_modified();
+ desc.set_end_sequence();
+ desc.set_can_expose_external_int();
return true;
case 0x0f: // MAC_W(Rm, Rn);
case 0x1f: // MAC_W(Rm, Rn);
case 0x2f: // MAC_W(Rm, Rn);
case 0x3f: // MAC_W(Rm, Rn);
- desc.regin[0] |= REGFLAG_R(REG_M) | REGFLAG_R(REG_N);
- desc.regin[1] |= REGFLAG_MACL | REGFLAG_MACH;
- desc.regout[0] |= REGFLAG_R(REG_M) | REGFLAG_R(REG_N);
- desc.regout[1] |= REGFLAG_MACL | REGFLAG_MACH;
+ desc.set_r_used(REG_M);
+ desc.set_r_used(REG_N);
+ desc.set_mac_used();
+ desc.set_r_modified(REG_M);
+ desc.set_r_modified(REG_N);
+ desc.set_mac_modified();
desc.cycles = 3;
return true;
case 0x10: // DT(Rn);
- desc.regin[0] |= REGFLAG_R(REG_N);
- desc.regin[1] |= REGFLAG_SR;
- desc.regout[0] |= REGFLAG_R(REG_N);
- desc.regout[1] |= REGFLAG_SR;
+ desc.set_r_used(REG_N);
+ desc.set_sr_used();
+ desc.set_r_modified(REG_N);
+ desc.set_sr_modified();
return true;
case 0x11: // CMPPZ(Rn);
case 0x15: // CMPPL(Rn);
- desc.regin[0] |= REGFLAG_R(REG_N);
- desc.regin[1] |= REGFLAG_SR;
- desc.regout[1] |= REGFLAG_SR;
+ desc.set_r_used(REG_N);
+ desc.set_sr_used();
+ desc.set_sr_modified();
return true;
case 0x12: // STSMMACL(Rn);
- desc.regin[0] |= REGFLAG_R(REG_N);
- desc.regin[1] |= REGFLAG_MACL;
- desc.regout[0] |= REGFLAG_R(REG_N);
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_r_used(REG_N);
+ desc.set_macl_used();
+ desc.set_r_modified(REG_N);
+ desc.set_writes_memory();
return true;
case 0x13: // STCMGBR(Rn);
- desc.regin[0] |= REGFLAG_R(REG_N);
- desc.regin[1] |= REGFLAG_GBR;
- desc.regout[0] |= REGFLAG_R(REG_N);
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_r_used(REG_N);
+ desc.set_gbr_used();
+ desc.set_r_modified(REG_N);
+ desc.set_writes_memory();
return true;
case 0x16: // LDSMMACL(Rn);
- desc.regin[0] |= REGFLAG_R(REG_M) | REGFLAG_R(REG_N);
- desc.regout[0] |= REGFLAG_R(REG_M) | REGFLAG_R(REG_N);
- desc.regout[1] |= REGFLAG_MACL;
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_r_used(REG_M);
+ desc.set_r_used(REG_N);
+ desc.set_r_modified(REG_M);
+ desc.set_r_modified(REG_N);
+ desc.set_macl_modified();
+ desc.set_reads_memory();
return true;
case 0x17: // LDCMGBR(Rn);
- desc.regin[0] |= REGFLAG_R(REG_N);
- desc.regout[0] |= REGFLAG_R(REG_N);
- desc.regout[1] |= REGFLAG_GBR;
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_r_used(REG_N);
+ desc.set_r_modified(REG_N);
+ desc.set_gbr_modified();
+ desc.set_reads_memory();
return true;
case 0x1a: // LDSMACL(Rn);
- desc.regin[0] |= REGFLAG_R(REG_N);
- desc.regout[1] |= REGFLAG_MACL;
+ desc.set_r_used(REG_N);
+ desc.set_macl_modified();
return true;
case 0x1b: // TAS(Rn);
- desc.regin[0] |= REGFLAG_R(REG_N);
- desc.regin[1] |= REGFLAG_SR;
- desc.regout[1] |= REGFLAG_SR;
+ desc.set_r_used(REG_N);
+ desc.set_sr_used();
+ desc.set_sr_modified();
desc.cycles = 4;
- desc.flags |= OPFLAG_READS_MEMORY | OPFLAG_WRITES_MEMORY;
+ desc.set_reads_memory();
+ desc.set_writes_memory();
return true;
case 0x1e: // LDCGBR(Rn);
- desc.regin[0] |= REGFLAG_R(REG_N);
- desc.regout[1] |= REGFLAG_GBR;
+ desc.set_r_used(REG_N);
+ desc.set_gbr_modified();
return true;
case 0x20: // SHAL(Rn);
case 0x21: // SHAR(Rn);
- desc.regin[0] |= REGFLAG_R(REG_N);
- desc.regout[0] |= REGFLAG_R(REG_N);
- desc.regout[1] |= REGFLAG_SR;
+ desc.set_r_used(REG_N);
+ desc.set_r_modified(REG_N);
+ desc.set_sr_modified();
return true;
case 0x22: // STSMPR(Rn);
- desc.regin[0] |= REGFLAG_R(REG_N);
- desc.regin[1] |= REGFLAG_PR;
- desc.regout[0] |= REGFLAG_R(REG_N);
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_r_used(REG_N);
+ desc.set_pr_used();
+ desc.set_r_modified(REG_N);
+ desc.set_writes_memory();
return true;
case 0x23: // STCMVBR(Rn);
- desc.regin[0] |= REGFLAG_R(REG_N);
- desc.regin[1] |= REGFLAG_VBR;
- desc.regout[0] |= REGFLAG_R(REG_N);
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_r_used(REG_N);
+ desc.set_vbr_used();
+ desc.set_r_modified(REG_N);
+ desc.set_writes_memory();
return true;
case 0x24: // ROTCL(Rn);
case 0x25: // ROTCR(Rn);
- desc.regin[0] |= REGFLAG_R(REG_N);
- desc.regin[1] |= REGFLAG_SR;
- desc.regout[0] |= REGFLAG_R(REG_N);
- desc.regout[1] |= REGFLAG_SR;
+ desc.set_r_used(REG_N);
+ desc.set_sr_used();
+ desc.set_r_modified(REG_N);
+ desc.set_sr_modified();
return true;
case 0x26: // LDSMPR(Rn);
- desc.regin[0] |= REGFLAG_R(REG_N);
- desc.regout[0] |= REGFLAG_R(REG_N);
- desc.regout[1] |= REGFLAG_PR;
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_r_used(REG_N);
+ desc.set_r_modified(REG_N);
+ desc.set_pr_modified();
+ desc.set_reads_memory();
return true;
case 0x27: // LDCMVBR(Rn);
- desc.regin[0] |= REGFLAG_R(REG_N);
- desc.regout[0] |= REGFLAG_R(REG_N);
- desc.regout[1] |= REGFLAG_VBR;
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_r_used(REG_N);
+ desc.set_r_modified(REG_N);
+ desc.set_vbr_modified();
+ desc.set_reads_memory();
return true;
case 0x2a: // LDSPR(Rn);
- desc.regin[0] |= REGFLAG_R(REG_N);
- desc.regout[1] |= REGFLAG_PR;
+ desc.set_r_used(REG_N);
+ desc.set_pr_modified();
return true;
case 0x2b: // JMP(Rm);
- desc.regin[0] |= REGFLAG_R(REG_M);
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.set_r_used(REG_M);
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
desc.targetpc = BRANCH_TARGET_DYNAMIC;
desc.delayslots = 1;
return true;
case 0x2e: // LDCVBR(Rn);
- desc.regin[0] |= REGFLAG_R(REG_N);
- desc.regout[1] |= REGFLAG_VBR;
+ desc.set_r_used(REG_N);
+ desc.set_vbr_modified();
return true;
case 0x0c: // NOP();
diff --git a/src/devices/cpu/sh/sh_fe.h b/src/devices/cpu/sh/sh_fe.h
new file mode 100644
index 00000000000..26439f8af8d
--- /dev/null
+++ b/src/devices/cpu/sh/sh_fe.h
@@ -0,0 +1,120 @@
+// license:BSD-3-Clause
+// copyright-holders:David Haywood, R. Belmont
+/***************************************************************************
+
+ shfe.h
+
+ Front end for SuperH recompiler
+
+***************************************************************************/
+#ifndef MAME_CPU_SH_SH_FE_H
+#define MAME_CPU_SH_SH_FE_H
+
+#pragma once
+
+#include "sh.h"
+
+#include "cpu/drcfe.h"
+
+
+class sh_common_execution::opcode_desc : public opcode_desc_base<opcode_desc, 32>
+{
+public:
+ enum
+ {
+ REG_R0 = 0,
+
+ REG_PR = REG_R0 + 16,
+ REG_SR,
+ REG_MACL,
+ REG_MACH,
+ REG_GBR,
+ REG_VBR,
+
+ REG_COUNT
+ };
+
+ offs_t physpc; // physical PC of this opcode
+
+ uint16_t opptr; // copy of opcode
+
+ uint32_t cycles; // number of cycles needed to execute
+
+ void set_r_used(unsigned n) { regin.set(REG_R0 + n); }
+ void set_pr_used() { regin.set(REG_PR); }
+ void set_sr_used() { regin.set(REG_SR); }
+ void set_macl_used() { regin.set(REG_MACL); }
+ void set_mach_used() { regin.set(REG_MACH); }
+ void set_mac_used() { set_macl_used(); set_mach_used(); }
+ void set_gbr_used() { regin.set(REG_GBR); }
+ void set_vbr_used() { regin.set(REG_VBR); }
+
+ void set_r_modified(unsigned n) { regout.set(REG_R0 + n); }
+ void set_pr_modified() { regout.set(REG_PR); }
+ void set_sr_modified() { regout.set(REG_SR); }
+ void set_macl_modified() { regout.set(REG_MACL); }
+ void set_mach_modified() { regout.set(REG_MACH); }
+ void set_mac_modified() { set_macl_modified(); set_mach_modified(); }
+ void set_gbr_modified() { regout.set(REG_GBR); }
+ void set_vbr_modified() { regout.set(REG_VBR); }
+
+ void set_reads_memory() { m_reads_memory = true; }
+ void set_writes_memory() { m_writes_memory = true; }
+ void set_can_expose_external_int() { m_can_expose_external_int = true; }
+
+ bool reads_memory() const { return m_reads_memory; }
+ bool writes_memory() const { return m_writes_memory; }
+ bool can_expose_external_int() const { return m_can_expose_external_int; }
+
+ // compute the exception PC
+ uint32_t epc() const { return in_delay_slot() ? (pc - 1) : pc; }
+
+ void reset(offs_t curpc, bool in_delay_slot)
+ {
+ static_assert(REG_COUNT <= 32);
+
+ opcode_desc_base::reset(curpc, in_delay_slot);
+
+ physpc = curpc;
+ opptr = 0;
+ cycles = 0;
+ m_reads_memory = false;
+ m_writes_memory = false;
+ m_can_expose_external_int = false;
+ }
+
+private:
+ bool m_reads_memory;
+ bool m_writes_memory;
+ bool m_can_expose_external_int;
+};
+
+
+class sh_common_execution::frontend : public drc_frontend_base<opcode_desc>
+{
+public:
+ frontend(sh_common_execution *device, uint32_t window_start, uint32_t window_end, uint32_t max_sequence);
+ virtual ~frontend();
+
+ opcode_desc const *describe_code(offs_t startpc);
+
+protected:
+ virtual uint16_t read_word(opcode_desc &desc);
+
+ virtual bool describe_group_0(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode);
+ virtual bool describe_group_4(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode);
+ virtual bool describe_group_15(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode) = 0;
+
+ sh_common_execution *m_sh;
+
+private:
+ bool describe(opcode_desc &desc, const opcode_desc *prev);
+
+ bool describe_group_2(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode);
+ bool describe_group_3(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode);
+ bool describe_group_6(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode);
+ bool describe_group_8(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode);
+ bool describe_group_12(opcode_desc &desc, const opcode_desc *prev, uint16_t opcode);
+};
+
+#endif // MAME_CPU_SH_SH_FE_H
diff --git a/src/devices/cpu/sharc/sharc.cpp b/src/devices/cpu/sharc/sharc.cpp
index 4104f82aab2..a7466fd012f 100644
--- a/src/devices/cpu/sharc/sharc.cpp
+++ b/src/devices/cpu/sharc/sharc.cpp
@@ -619,7 +619,7 @@ void adsp21062_device::device_start()
m_drcuml->symbol_add(&m_core->lstkp, sizeof(m_core->lstkp), "lstkp");
m_drcuml->symbol_add(&m_core->px, sizeof(m_core->px), "px");
- m_drcfe = std::make_unique<sharc_frontend>(this, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, COMPILE_MAX_SEQUENCE);
+ m_drcfe = std::make_unique<frontend>(this, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, COMPILE_MAX_SEQUENCE);
for (int i = 0; i < 16; i++)
m_regmap[i] = uml::mem(&m_core->r[i]);
diff --git a/src/devices/cpu/sharc/sharc.h b/src/devices/cpu/sharc/sharc.h
index b11b47f8688..0094437238f 100644
--- a/src/devices/cpu/sharc/sharc.h
+++ b/src/devices/cpu/sharc/sharc.h
@@ -5,16 +5,11 @@
#pragma once
-#include "cpu/drcfe.h"
#include "cpu/drcuml.h"
-class sharc_frontend;
-
class adsp21062_device : public cpu_device
{
- friend class sharc_frontend;
-
public:
enum sharc_boot_mode
{
@@ -48,30 +43,6 @@ public:
uint32_t iop_r(offs_t offset);
void iop_w(offs_t offset, uint32_t data);
- enum ASTAT_FLAGS : uint32_t
- {
- // ASTAT flags
- AZ = 0x000001, // ALU result zero
- AV = 0x000002, // ALU overflow
- AN = 0x000004, // ALU result negative
- AC = 0x000008, // ALU fixed-point carry
- AS = 0x000010, // ALU X input sign
- AI = 0x000020, // ALU floating-point invalid operation
- MN = 0x000040, // Multiplier result negative
- MV = 0x000080, // Multiplier overflow
- MU = 0x000100, // Multiplier underflow
- MI = 0x000200, // Multiplier floating-point invalid operation
- AF = 0x000400,
- SV = 0x000800, // Shifter overflow
- SZ = 0x001000, // Shifter result zero
- SS = 0x002000, // Shifter input sign
- BTF = 0x040000, // Bit Test Flag
- FLG0 = 0x080000, // FLAG0
- FLG1 = 0x100000, // FLAG1
- FLG2 = 0x200000, // FLAG2
- FLG3 = 0x400000 // FLAG3
- };
-
enum ASTAT_SHIFT
{
AZ_SHIFT = 0,
@@ -148,6 +119,27 @@ protected:
void data_4m(address_map &map) ATTR_COLD;
private:
+ // ASTAT flags
+ static constexpr uint32_t AZ = 0x0000'0001; // ALU result zero
+ static constexpr uint32_t AV = 0x0000'0002; // ALU overflow
+ static constexpr uint32_t AN = 0x0000'0004; // ALU result negative
+ static constexpr uint32_t AC = 0x0000'0008; // ALU fixed-point carry
+ static constexpr uint32_t AS = 0x0000'0010; // ALU X input sign
+ static constexpr uint32_t AI = 0x0000'0020; // ALU floating-point invalid operation
+ static constexpr uint32_t MN = 0x0000'0040; // Multiplier result negative
+ 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 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
+ static constexpr uint32_t BTF = 0x0004'0000; // Bit Test Flag
+ static constexpr uint32_t FLG0 = 0x0008'0000; // FLAG0
+ static constexpr uint32_t FLG1 = 0x0010'0000; // FLAG1
+ static constexpr uint32_t FLG2 = 0x0020'0000; // FLAG2
+ static constexpr uint32_t FLG3 = 0x0040'0000; // FLAG3
+
// STKY flags
static constexpr uint32_t AUS = 0x0000'0001; // ALU floating-point underflow
static constexpr uint32_t AVS = 0x0000'0002; // ALU floating-point overflow
@@ -242,6 +234,9 @@ private:
struct alignas(16) sharc_internal_state;
+ class frontend;
+ class opcode_desc;
+
static const SHARC_OP s_sharc_opcode_table[];
static const size_t s_num_ops;
@@ -259,7 +254,7 @@ private:
// UML stuff
drc_cache m_cache;
std::unique_ptr<drcuml_state> m_drcuml;
- std::unique_ptr<sharc_frontend> m_drcfe;
+ std::unique_ptr<frontend> m_drcfe;
uml::parameter m_regmap[16];
uml::code_handle *m_entry;
diff --git a/src/devices/cpu/sharc/sharcdrc.cpp b/src/devices/cpu/sharc/sharcdrc.cpp
index 5ec296217ed..f3ecdfe3b1a 100644
--- a/src/devices/cpu/sharc/sharcdrc.cpp
+++ b/src/devices/cpu/sharc/sharcdrc.cpp
@@ -13,11 +13,11 @@
#include "sharcfe.h"
#include "sharcinternal.ipp"
-#include "cpu/drcfe.h"
#include "cpu/drcuml.h"
#include "cpu/drcumlsh.h"
+#define USE_ASTAT_ELISION 1
#define USE_FAST_APPROX 0
#define USE_SWAPDQ 0
@@ -77,21 +77,21 @@
#define MRF mem(&m_core->mrf)
#define MRB mem(&m_core->mrb)
-#define AZ_CALC_REQUIRED ((desc->regreq[0] & 0x00010000) || desc->flags & OPFLAG_IN_DELAY_SLOT)
-#define AV_CALC_REQUIRED ((desc->regreq[0] & 0x00020000) || desc->flags & OPFLAG_IN_DELAY_SLOT)
-#define AN_CALC_REQUIRED ((desc->regreq[0] & 0x00040000) || desc->flags & OPFLAG_IN_DELAY_SLOT)
-#define AC_CALC_REQUIRED ((desc->regreq[0] & 0x00080000) || desc->flags & OPFLAG_IN_DELAY_SLOT)
-#define AS_CALC_REQUIRED ((desc->regreq[0] & 0x00100000) || desc->flags & OPFLAG_IN_DELAY_SLOT)
-#define AI_CALC_REQUIRED ((desc->regreq[0] & 0x00200000) || desc->flags & OPFLAG_IN_DELAY_SLOT)
-#define MN_CALC_REQUIRED ((desc->regreq[0] & 0x00400000) || desc->flags & OPFLAG_IN_DELAY_SLOT)
-#define MV_CALC_REQUIRED ((desc->regreq[0] & 0x00800000) || desc->flags & OPFLAG_IN_DELAY_SLOT)
-#define MU_CALC_REQUIRED ((desc->regreq[0] & 0x01000000) || desc->flags & OPFLAG_IN_DELAY_SLOT)
-#define MI_CALC_REQUIRED ((desc->regreq[0] & 0x02000000) || desc->flags & OPFLAG_IN_DELAY_SLOT)
-#define SV_CALC_REQUIRED ((desc->regreq[0] & 0x04000000) || desc->flags & OPFLAG_IN_DELAY_SLOT)
-#define SZ_CALC_REQUIRED ((desc->regreq[0] & 0x08000000) || desc->flags & OPFLAG_IN_DELAY_SLOT)
-#define SS_CALC_REQUIRED ((desc->regreq[0] & 0x10000000) || desc->flags & OPFLAG_IN_DELAY_SLOT)
-#define BTF_CALC_REQUIRED ((desc->regreq[0] & 0x20000000) || desc->flags & OPFLAG_IN_DELAY_SLOT)
-#define AF_CALC_REQUIRED ((desc->regreq[0] & 0x40000000) || desc->flags & OPFLAG_IN_DELAY_SLOT)
+#define AZ_CALC_REQUIRED (!USE_ASTAT_ELISION || desc->az_calc_required())
+#define AV_CALC_REQUIRED (!USE_ASTAT_ELISION || desc->av_calc_required())
+#define AN_CALC_REQUIRED (!USE_ASTAT_ELISION || desc->an_calc_required())
+#define AC_CALC_REQUIRED (!USE_ASTAT_ELISION || desc->ac_calc_required())
+#define AS_CALC_REQUIRED (!USE_ASTAT_ELISION || desc->as_calc_required())
+#define AI_CALC_REQUIRED (!USE_ASTAT_ELISION || desc->ai_calc_required())
+#define MN_CALC_REQUIRED (!USE_ASTAT_ELISION || desc->mn_calc_required())
+#define MV_CALC_REQUIRED (!USE_ASTAT_ELISION || desc->mv_calc_required())
+#define MU_CALC_REQUIRED (!USE_ASTAT_ELISION || desc->mu_calc_required())
+#define MI_CALC_REQUIRED (!USE_ASTAT_ELISION || desc->mi_calc_required())
+#define SV_CALC_REQUIRED (!USE_ASTAT_ELISION || desc->sv_calc_required())
+#define SZ_CALC_REQUIRED (!USE_ASTAT_ELISION || desc->sz_calc_required())
+#define SS_CALC_REQUIRED (!USE_ASTAT_ELISION || desc->ss_calc_required())
+#define BTF_CALC_REQUIRED (!USE_ASTAT_ELISION || desc->btf_calc_required())
+#define AF_CALC_REQUIRED (!USE_ASTAT_ELISION || desc->af_calc_required())
namespace {
@@ -1160,7 +1160,7 @@ void adsp21062_device::compile_block(offs_t pc)
{
// determine the last instruction in this sequence
seqlast = seqhead;
- while (seqlast && !(seqlast->flags & OPFLAG_END_SEQUENCE))
+ while (seqlast && !seqlast->end_sequence())
seqlast = seqlast->next();
assert(seqlast != nullptr);
@@ -1185,7 +1185,7 @@ void adsp21062_device::compile_block(offs_t pc)
}
// label this instruction, if it may be jumped to locally
- if (seqhead->flags & OPFLAG_IS_BRANCH_TARGET)
+ if (seqhead->is_branch_target())
UML_LABEL(block, seqhead->pc | 0x80000000);
// iterate over instructions in the sequence and compile them
@@ -1200,7 +1200,7 @@ void adsp21062_device::compile_block(offs_t pc)
}
uint32_t nextpc;
- if (seqlast->flags & OPFLAG_RETURN_TO_START)
+ if (seqlast->return_to_start())
nextpc = pc; // if we need to return to the start, do it
else
nextpc = seqlast->pc + (seqlast->skipslots + 1); // otherwise we just go to the next instruction
@@ -1352,14 +1352,14 @@ void adsp21062_device::static_generate_reset_cache()
void adsp21062_device::generate_sequence_instruction(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc, bool last_delayslot)
{
/* add an entry for the log */
-// if (m_drcuml->logging() && !(desc->flags & OPFLAG_VIRTUAL_NOOP))
-// log_add_disasm_comment(block, desc->pc, desc->opptr.l[0]);
+// if (m_drcuml->logging() && !desc->virtual_noop())
+// 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
/* accumulate total cycles */
- compiler.cycles += desc->cycles;
+ compiler.cycles += 1;
/* update the icount map variable */
UML_MAPVAR(block, MAPVAR_CYCLES, compiler.cycles); // mapvar CYCLES,compiler.cycles
@@ -1372,33 +1372,25 @@ void adsp21062_device::generate_sequence_instruction(drcuml_block &block, compil
UML_DEBUG(block, desc->pc); // debug desc->pc
}
- /* if we hit an unmapped address, fatal error */
- if (desc->flags & OPFLAG_COMPILER_UNMAPPED)
- {
- UML_MOV(block, mem(&m_core->pc), desc->pc); // mov [pc],desc->pc
- save_fast_iregs(block); // <save fastregs>
- UML_EXIT(block, EXECUTE_UNMAPPED_CODE); // exit EXECUTE_UNMAPPED_CODE
- }
-
// handle a special case where call is used as the last operation in a loop
- if ((desc->userflags & OP_USERFLAG_CALL) && (desc->userflags & OP_USERFLAG_LOOP))
+ if (desc->call() && desc->loop())
{
UML_MOV(block, I0, desc->pc);
UML_CALLH(block, *m_call_loop_check);
}
/* if this is an invalid opcode, generate the exception now */
-// if (desc->flags & OPFLAG_INVALID_OPCODE)
+// if (desc->invalid_opcode())
// UML_EXH(block, *m_exception[EXCEPTION_PROGRAM], 0x80000); // exh exception_program,0x80000
/* unless this is a virtual no-op, it's a regular instruction */
- if (!(desc->flags & OPFLAG_VIRTUAL_NOOP))
+ if (!desc->virtual_noop())
{
/* 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.q[0]); // dmov [arg64],*desc->opptr.q
+ UML_DMOV(block, mem(&m_core->arg64), desc->opptr); // dmov [arg64],*desc->opptr
UML_CALLC(block, cfunc_unimplemented, this); // callc cfunc_unimplemented,ppc
}
}
@@ -1438,34 +1430,31 @@ void adsp21062_device::generate_sequence_instruction(drcuml_block &block, compil
// insert loop check at this instruction if needed
- if (desc->userflags & OP_USERFLAG_LOOP)
+ if (desc->loop())
{
UML_DMOV(block, I0, (uint64_t(compiler.cycles) << 32) | desc->pc);
UML_CALLH(block, *m_loop_check);
}
// copy ASTAT bits over for conditional loop
- if (desc->userflags & OP_USERFLAG_ASTAT_DELAY_COPY)
- {
- if (desc->userflags & OP_USERFLAG_ASTAT_DELAY_COPY_AZ)
- UML_MOV(block, mem(&m_core->astat_delay_copy.az), mem(&m_core->astat_drc.az));
- if (desc->userflags & OP_USERFLAG_ASTAT_DELAY_COPY_AN)
- UML_MOV(block, mem(&m_core->astat_delay_copy.an), mem(&m_core->astat_drc.an));
- if (desc->userflags & OP_USERFLAG_ASTAT_DELAY_COPY_AV)
- UML_MOV(block, mem(&m_core->astat_delay_copy.av), mem(&m_core->astat_drc.av));
- if (desc->userflags & OP_USERFLAG_ASTAT_DELAY_COPY_AC)
- UML_MOV(block, mem(&m_core->astat_delay_copy.ac), mem(&m_core->astat_drc.ac));
- if (desc->userflags & OP_USERFLAG_ASTAT_DELAY_COPY_MN)
- UML_MOV(block, mem(&m_core->astat_delay_copy.mn), mem(&m_core->astat_drc.mn));
- if (desc->userflags & OP_USERFLAG_ASTAT_DELAY_COPY_MV)
- UML_MOV(block, mem(&m_core->astat_delay_copy.mv), mem(&m_core->astat_drc.mv));
- if (desc->userflags & OP_USERFLAG_ASTAT_DELAY_COPY_SV)
- UML_MOV(block, mem(&m_core->astat_delay_copy.sv), mem(&m_core->astat_drc.sv));
- if (desc->userflags & OP_USERFLAG_ASTAT_DELAY_COPY_SZ)
- UML_MOV(block, mem(&m_core->astat_delay_copy.sz), mem(&m_core->astat_drc.sz));
- if (desc->userflags & OP_USERFLAG_ASTAT_DELAY_COPY_BTF)
- UML_MOV(block, mem(&m_core->astat_delay_copy.btf), mem(&m_core->astat_drc.btf));
- }
+ if (desc->astat_delay_copy_az())
+ UML_MOV(block, mem(&m_core->astat_delay_copy.az), mem(&m_core->astat_drc.az));
+ if (desc->astat_delay_copy_an())
+ UML_MOV(block, mem(&m_core->astat_delay_copy.an), mem(&m_core->astat_drc.an));
+ if (desc->astat_delay_copy_av())
+ UML_MOV(block, mem(&m_core->astat_delay_copy.av), mem(&m_core->astat_drc.av));
+ if (desc->astat_delay_copy_ac())
+ UML_MOV(block, mem(&m_core->astat_delay_copy.ac), mem(&m_core->astat_drc.ac));
+ if (desc->astat_delay_copy_mn())
+ UML_MOV(block, mem(&m_core->astat_delay_copy.mn), mem(&m_core->astat_drc.mn));
+ if (desc->astat_delay_copy_mv())
+ UML_MOV(block, mem(&m_core->astat_delay_copy.mv), mem(&m_core->astat_drc.mv));
+ if (desc->astat_delay_copy_sv())
+ UML_MOV(block, mem(&m_core->astat_delay_copy.sv), mem(&m_core->astat_drc.sv));
+ if (desc->astat_delay_copy_sz())
+ UML_MOV(block, mem(&m_core->astat_delay_copy.sz), mem(&m_core->astat_drc.sz));
+ if (desc->astat_delay_copy_btf())
+ UML_MOV(block, mem(&m_core->astat_delay_copy.btf), mem(&m_core->astat_drc.btf));
}
void adsp21062_device::generate_update_cycles(drcuml_block &block, compiler_state &compiler, uml::parameter param, bool allow_exception)
@@ -1714,7 +1703,7 @@ void adsp21062_device::generate_call(drcuml_block &block, compiler_state &compil
}
// if this is the last instruction of a loop, we need to use the return PC from the resolved loop
- if (desc->userflags & OP_USERFLAG_CALL && desc->userflags & OP_USERFLAG_LOOP)
+ if (desc->call() && desc->loop())
{
UML_MOV(block, I0, mem(&m_core->temp_return));
}
@@ -1732,7 +1721,7 @@ void adsp21062_device::generate_call(drcuml_block &block, compiler_state &compil
if (desc->targetpc != BRANCH_TARGET_DYNAMIC)
{
generate_update_cycles(block, compiler_temp, desc->targetpc, true);
- if (desc->flags & OPFLAG_INTRABLOCK_BRANCH)
+ if (desc->intrablock_branch())
UML_JMP(block, desc->targetpc | 0x80000000);
else
UML_HASHJMP(block, 0, desc->targetpc, *m_nocode);
@@ -1799,7 +1788,7 @@ void adsp21062_device::generate_jump(drcuml_block &block, compiler_state &compil
if (desc->targetpc != BRANCH_TARGET_DYNAMIC)
{
generate_update_cycles(block, compiler_temp, desc->targetpc, true);
- if (desc->flags & OPFLAG_INTRABLOCK_BRANCH)
+ if (desc->intrablock_branch())
UML_JMP(block, desc->targetpc | 0x80000000); // jmp targetpc | 0x80000000
else
UML_HASHJMP(block, 0, desc->targetpc, *m_nocode); // hashjmp 0,targetpc,nocode
@@ -2175,42 +2164,42 @@ void adsp21062_device::generate_write_ureg(drcuml_block &block, compiler_state &
UML_XOR(block, I1, mem(&m_core->astat), data);
UML_MOV(block, mem(&m_core->astat), data & (FLG0 | FLG1 | FLG2 | FLG3));
UML_MOV(block, mem(&m_core->astat_drc.cacc), BIT(data, 24, 8));
- UML_MOV(block, ASTAT_AF, BIT(data, AF_SHIFT));
- UML_MOV(block, ASTAT_BTF, BIT(data, BTF_SHIFT));
- UML_MOV(block, ASTAT_SS, BIT(data, SS_SHIFT));
- UML_MOV(block, ASTAT_SZ, BIT(data, SZ_SHIFT));
- UML_MOV(block, ASTAT_SV, BIT(data, SV_SHIFT));
- UML_MOV(block, ASTAT_MI, BIT(data, MI_SHIFT));
- UML_MOV(block, ASTAT_MU, BIT(data, MU_SHIFT));
- UML_MOV(block, ASTAT_MV, BIT(data, MV_SHIFT));
- UML_MOV(block, ASTAT_MN, BIT(data, MN_SHIFT));
- UML_MOV(block, ASTAT_AI, BIT(data, AI_SHIFT));
- UML_MOV(block, ASTAT_AS, BIT(data, AS_SHIFT));
- UML_MOV(block, ASTAT_AC, BIT(data, AC_SHIFT));
- UML_MOV(block, ASTAT_AN, BIT(data, AN_SHIFT));
- UML_MOV(block, ASTAT_AV, BIT(data, AV_SHIFT));
- UML_MOV(block, ASTAT_AZ, BIT(data, AZ_SHIFT));
+ if (AF_CALC_REQUIRED) UML_MOV(block, ASTAT_AF, BIT(data, AF_SHIFT));
+ if (BTF_CALC_REQUIRED) UML_MOV(block, ASTAT_BTF, BIT(data, BTF_SHIFT));
+ if (SS_CALC_REQUIRED) UML_MOV(block, ASTAT_SS, BIT(data, SS_SHIFT));
+ if (SZ_CALC_REQUIRED) UML_MOV(block, ASTAT_SZ, BIT(data, SZ_SHIFT));
+ if (SV_CALC_REQUIRED) UML_MOV(block, ASTAT_SV, BIT(data, SV_SHIFT));
+ if (MI_CALC_REQUIRED) UML_MOV(block, ASTAT_MI, BIT(data, MI_SHIFT));
+ if (MU_CALC_REQUIRED) UML_MOV(block, ASTAT_MU, BIT(data, MU_SHIFT));
+ if (MV_CALC_REQUIRED) UML_MOV(block, ASTAT_MV, BIT(data, MV_SHIFT));
+ if (MN_CALC_REQUIRED) UML_MOV(block, ASTAT_MN, BIT(data, MN_SHIFT));
+ if (AI_CALC_REQUIRED) UML_MOV(block, ASTAT_AI, BIT(data, AI_SHIFT));
+ if (AS_CALC_REQUIRED) UML_MOV(block, ASTAT_AS, BIT(data, AS_SHIFT));
+ if (AC_CALC_REQUIRED) UML_MOV(block, ASTAT_AC, BIT(data, AC_SHIFT));
+ if (AN_CALC_REQUIRED) UML_MOV(block, ASTAT_AN, BIT(data, AN_SHIFT));
+ if (AV_CALC_REQUIRED) UML_MOV(block, ASTAT_AV, BIT(data, AV_SHIFT));
+ if (AZ_CALC_REQUIRED) UML_MOV(block, ASTAT_AZ, BIT(data, AZ_SHIFT));
}
else
{
UML_XOR(block, I1, I0, mem(&m_core->astat));
UML_AND(block, mem(&m_core->astat), I0, FLG0 | FLG1 | FLG2 | FLG3);
UML_BFXU(block, mem(&m_core->astat_drc.cacc), I0, 24, 8);
- UML_BFXU(block, ASTAT_AF, I0, AF_SHIFT, 1);
- UML_BFXU(block, ASTAT_BTF, I0, BTF_SHIFT, 1);
- UML_BFXU(block, ASTAT_SS, I0, SS_SHIFT, 1);
- UML_BFXU(block, ASTAT_SZ, I0, SZ_SHIFT, 1);
- UML_BFXU(block, ASTAT_SV, I0, SV_SHIFT, 1);
- UML_BFXU(block, ASTAT_MI, I0, MI_SHIFT, 1);
- UML_BFXU(block, ASTAT_MU, I0, MU_SHIFT, 1);
- UML_BFXU(block, ASTAT_MV, I0, MV_SHIFT, 1);
- UML_BFXU(block, ASTAT_MN, I0, MN_SHIFT, 1);
- UML_BFXU(block, ASTAT_AI, I0, AI_SHIFT, 1);
- UML_BFXU(block, ASTAT_AS, I0, AS_SHIFT, 1);
- UML_BFXU(block, ASTAT_AC, I0, AC_SHIFT, 1);
- UML_BFXU(block, ASTAT_AN, I0, AN_SHIFT, 1);
- UML_BFXU(block, ASTAT_AV, I0, AV_SHIFT, 1);
- UML_BFXU(block, ASTAT_AZ, I0, AZ_SHIFT, 1);
+ if (AF_CALC_REQUIRED) UML_BFXU(block, ASTAT_AF, I0, AF_SHIFT, 1);
+ if (BTF_CALC_REQUIRED) UML_BFXU(block, ASTAT_BTF, I0, BTF_SHIFT, 1);
+ if (SS_CALC_REQUIRED) UML_BFXU(block, ASTAT_SS, I0, SS_SHIFT, 1);
+ if (SZ_CALC_REQUIRED) UML_BFXU(block, ASTAT_SZ, I0, SZ_SHIFT, 1);
+ if (SV_CALC_REQUIRED) UML_BFXU(block, ASTAT_SV, I0, SV_SHIFT, 1);
+ if (MI_CALC_REQUIRED) UML_BFXU(block, ASTAT_MI, I0, MI_SHIFT, 1);
+ if (MU_CALC_REQUIRED) UML_BFXU(block, ASTAT_MU, I0, MU_SHIFT, 1);
+ if (MV_CALC_REQUIRED) UML_BFXU(block, ASTAT_MV, I0, MV_SHIFT, 1);
+ if (MN_CALC_REQUIRED) UML_BFXU(block, ASTAT_MN, I0, MN_SHIFT, 1);
+ if (AI_CALC_REQUIRED) UML_BFXU(block, ASTAT_AI, I0, AI_SHIFT, 1);
+ if (AS_CALC_REQUIRED) UML_BFXU(block, ASTAT_AS, I0, AS_SHIFT, 1);
+ if (AC_CALC_REQUIRED) UML_BFXU(block, ASTAT_AC, I0, AC_SHIFT, 1);
+ if (AN_CALC_REQUIRED) UML_BFXU(block, ASTAT_AN, I0, AN_SHIFT, 1);
+ if (AV_CALC_REQUIRED) UML_BFXU(block, ASTAT_AV, I0, AV_SHIFT, 1);
+ if (AZ_CALC_REQUIRED) UML_BFXU(block, ASTAT_AZ, I0, AZ_SHIFT, 1);
}
UML_SHL(block, I0, MODE2, FLG0_SHIFT - 15);
UML_AND(block, I0, I0, I1);
@@ -2284,7 +2273,7 @@ void adsp21062_device::generate_write_ureg(drcuml_block &block, compiler_state &
bool adsp21062_device::generate_opcode(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc)
{
- uint64_t opcode = desc->opptr.q[0];
+ uint64_t const opcode = desc->opptr;
switch ((opcode >> 45) & 7)
{
@@ -2862,72 +2851,72 @@ bool adsp21062_device::generate_opcode(drcuml_block &block, compiler_state &comp
break;
case 0xc: // ASTAT
// TODO: does this need delay?
- if (data & ASTAT_FLAGS::AZ)
+ if (AZ_CALC_REQUIRED && (data & AZ))
UML_MOV(block, ASTAT_AZ, 1);
- if (data & ASTAT_FLAGS::AV)
+ if (AV_CALC_REQUIRED && (data & AV))
UML_MOV(block, ASTAT_AV, 1);
- if (data & ASTAT_FLAGS::AN)
+ if (AN_CALC_REQUIRED && (data & AN))
UML_MOV(block, ASTAT_AN, 1);
- if (data & ASTAT_FLAGS::AC)
+ if (AC_CALC_REQUIRED && (data & AC))
UML_MOV(block, ASTAT_AC, 1);
- if (data & ASTAT_FLAGS::AS)
+ if (AS_CALC_REQUIRED && (data & AS))
UML_MOV(block, ASTAT_AS, 1);
- if (data & ASTAT_FLAGS::AI)
+ if (AI_CALC_REQUIRED && (data & AI))
UML_MOV(block, ASTAT_AI, 1);
- if (data & ASTAT_FLAGS::MN)
+ if (MN_CALC_REQUIRED && (data & MN))
UML_MOV(block, ASTAT_MN, 1);
- if (data & ASTAT_FLAGS::MV)
+ if (MV_CALC_REQUIRED && (data & MV))
UML_MOV(block, ASTAT_MV, 1);
- if (data & ASTAT_FLAGS::MU)
+ if (MU_CALC_REQUIRED && (data & MU))
UML_MOV(block, ASTAT_MU, 1);
- if (data & ASTAT_FLAGS::MI)
+ if (MI_CALC_REQUIRED && (data & MI))
UML_MOV(block, ASTAT_MI, 1);
- if (data & ASTAT_FLAGS::AF)
+ if (AF_CALC_REQUIRED && (data & AF))
UML_MOV(block, ASTAT_AF, 1);
- if (data & ASTAT_FLAGS::SV)
+ if (SV_CALC_REQUIRED && (data & SV))
UML_MOV(block, ASTAT_SV, 1);
- if (data & ASTAT_FLAGS::SZ)
+ if (SZ_CALC_REQUIRED && (data & SZ))
UML_MOV(block, ASTAT_SZ, 1);
- if (data & ASTAT_FLAGS::SS)
+ if (SS_CALC_REQUIRED && (data & SS))
UML_MOV(block, ASTAT_SS, 1);
- if (data & ASTAT_FLAGS::BTF)
+ if (BTF_CALC_REQUIRED && (data & BTF))
UML_MOV(block, ASTAT_BTF, 1);
- if (data & (ASTAT_FLAGS::FLG0 | ASTAT_FLAGS::FLG1 | ASTAT_FLAGS::FLG2 | ASTAT_FLAGS::FLG3))
+ if (data & (FLG0 | FLG1 | FLG2 | FLG3))
{
UML_MOV(block, I0, mem(&m_core->astat));
- UML_ROLAND(block, I1, MODE2, FLG0_SHIFT - 15, data & (ASTAT_FLAGS::FLG0 | ASTAT_FLAGS::FLG1 | ASTAT_FLAGS::FLG2 | ASTAT_FLAGS::FLG3));
- UML_OR(block, mem(&m_core->astat), I0, data & (ASTAT_FLAGS::FLG0 | ASTAT_FLAGS::FLG1 | ASTAT_FLAGS::FLG2 | ASTAT_FLAGS::FLG3));
+ UML_ROLAND(block, I1, MODE2, FLG0_SHIFT - 15, data & (FLG0 | FLG1 | FLG2 | FLG3));
+ UML_OR(block, mem(&m_core->astat), I0, data & (FLG0 | FLG1 | FLG2 | FLG3));
UML_XOR(block, I0, I0, 0xffffffff);
UML_AND(block, I0, I0, I1);
}
- if (data & ASTAT_FLAGS::FLG0)
+ if (data & FLG0)
{
uml::code_label const skip = compiler.labelnum++;
- UML_TEST(block, I0, ASTAT_FLAGS::FLG0);
+ UML_TEST(block, I0, FLG0);
UML_JMPc(block, COND_Z, skip);
UML_CALLC(block, cfunc_update_flag_out<0>, this);
UML_LABEL(block, skip);
}
- if (data & ASTAT_FLAGS::FLG1)
+ if (data & FLG1)
{
uml::code_label const skip = compiler.labelnum++;
- UML_TEST(block, I0, ASTAT_FLAGS::FLG1);
+ UML_TEST(block, I0, FLG1);
UML_JMPc(block, COND_Z, skip);
UML_CALLC(block, cfunc_update_flag_out<1>, this);
UML_LABEL(block, skip);
}
- if (data & ASTAT_FLAGS::FLG2)
+ if (data & FLG2)
{
uml::code_label const skip = compiler.labelnum++;
- UML_TEST(block, I0, ASTAT_FLAGS::FLG2);
+ UML_TEST(block, I0, FLG2);
UML_JMPc(block, COND_Z, skip);
UML_CALLC(block, cfunc_update_flag_out<2>, this);
UML_LABEL(block, skip);
}
- if (data & ASTAT_FLAGS::FLG3)
+ if (data & FLG3)
{
uml::code_label const skip = compiler.labelnum++;
- UML_TEST(block, I0, ASTAT_FLAGS::FLG3);
+ UML_TEST(block, I0, FLG3);
UML_JMPc(block, COND_Z, skip);
UML_CALLC(block, cfunc_update_flag_out<3>, this);
UML_LABEL(block, skip);
@@ -2975,71 +2964,71 @@ bool adsp21062_device::generate_opcode(drcuml_block &block, compiler_state &comp
break;
case 0xc: // ASTAT
// TODO: does this need delay?
- if (data & ASTAT_FLAGS::AZ)
+ if (AZ_CALC_REQUIRED && (data & AZ))
UML_MOV(block, ASTAT_AZ, 0);
- if (data & ASTAT_FLAGS::AV)
+ if (AV_CALC_REQUIRED && (data & AV))
UML_MOV(block, ASTAT_AV, 0);
- if (data & ASTAT_FLAGS::AN)
+ if (AN_CALC_REQUIRED && (data & AN))
UML_MOV(block, ASTAT_AN, 0);
- if (data & ASTAT_FLAGS::AC)
+ if (AC_CALC_REQUIRED && (data & AC))
UML_MOV(block, ASTAT_AC, 0);
- if (data & ASTAT_FLAGS::AS)
+ if (AS_CALC_REQUIRED && (data & AS))
UML_MOV(block, ASTAT_AS, 0);
- if (data & ASTAT_FLAGS::AI)
+ if (AI_CALC_REQUIRED && (data & AI))
UML_MOV(block, ASTAT_AI, 0);
- if (data & ASTAT_FLAGS::MN)
+ if (MN_CALC_REQUIRED && (data & MN))
UML_MOV(block, ASTAT_MN, 0);
- if (data & ASTAT_FLAGS::MV)
+ if (MV_CALC_REQUIRED && (data & MV))
UML_MOV(block, ASTAT_MV, 0);
- if (data & ASTAT_FLAGS::MU)
+ if (MU_CALC_REQUIRED && (data & MU))
UML_MOV(block, ASTAT_MU, 0);
- if (data & ASTAT_FLAGS::MI)
+ if (MI_CALC_REQUIRED && (data & MI))
UML_MOV(block, ASTAT_MI, 0);
- if (data & ASTAT_FLAGS::AF)
+ if (AF_CALC_REQUIRED && (data & AF))
UML_MOV(block, ASTAT_AF, 0);
- if (data & ASTAT_FLAGS::SV)
+ if (SV_CALC_REQUIRED && (data & SV))
UML_MOV(block, ASTAT_SV, 0);
- if (data & ASTAT_FLAGS::SZ)
+ if (SZ_CALC_REQUIRED && (data & SZ))
UML_MOV(block, ASTAT_SZ, 0);
- if (data & ASTAT_FLAGS::SS)
+ if (SS_CALC_REQUIRED && (data & SS))
UML_MOV(block, ASTAT_SS, 0);
- if (data & ASTAT_FLAGS::BTF)
+ if (BTF_CALC_REQUIRED && (data & BTF))
UML_MOV(block, ASTAT_BTF, 0);
- if (data & (ASTAT_FLAGS::FLG0 | ASTAT_FLAGS::FLG1 | ASTAT_FLAGS::FLG2 | ASTAT_FLAGS::FLG3))
+ if (data & (FLG0 | FLG1 | FLG2 | FLG3))
{
UML_MOV(block, I0, mem(&m_core->astat));
- UML_ROLAND(block, I1, MODE2, FLG0_SHIFT - 15, data & (ASTAT_FLAGS::FLG0 | ASTAT_FLAGS::FLG1 | ASTAT_FLAGS::FLG2 | ASTAT_FLAGS::FLG3));
- UML_AND(block, mem(&m_core->astat), I0, ~data & (ASTAT_FLAGS::FLG0 | ASTAT_FLAGS::FLG1 | ASTAT_FLAGS::FLG2 | ASTAT_FLAGS::FLG3));
+ UML_ROLAND(block, I1, MODE2, FLG0_SHIFT - 15, data & (FLG0 | FLG1 | FLG2 | FLG3));
+ UML_AND(block, mem(&m_core->astat), I0, ~data & (FLG0 | FLG1 | FLG2 | FLG3));
UML_AND(block, I0, I0, I1);
}
- if (data & ASTAT_FLAGS::FLG0)
+ if (data & FLG0)
{
uml::code_label const skip = compiler.labelnum++;
- UML_TEST(block, I0, ASTAT_FLAGS::FLG0);
+ UML_TEST(block, I0, FLG0);
UML_JMPc(block, COND_Z, skip);
UML_CALLC(block, cfunc_update_flag_out<0>, this);
UML_LABEL(block, skip);
}
- if (data & ASTAT_FLAGS::FLG1)
+ if (data & FLG1)
{
uml::code_label const skip = compiler.labelnum++;
- UML_TEST(block, I0, ASTAT_FLAGS::FLG1);
+ UML_TEST(block, I0, FLG1);
UML_JMPc(block, COND_Z, skip);
UML_CALLC(block, cfunc_update_flag_out<1>, this);
UML_LABEL(block, skip);
}
- if (data & ASTAT_FLAGS::FLG2)
+ if (data & FLG2)
{
uml::code_label const skip = compiler.labelnum++;
- UML_TEST(block, I0, ASTAT_FLAGS::FLG2);
+ UML_TEST(block, I0, FLG2);
UML_JMPc(block, COND_Z, skip);
UML_CALLC(block, cfunc_update_flag_out<2>, this);
UML_LABEL(block, skip);
}
- if (data & ASTAT_FLAGS::FLG3)
+ if (data & FLG3)
{
uml::code_label const skip = compiler.labelnum++;
- UML_TEST(block, I0, ASTAT_FLAGS::FLG3);
+ UML_TEST(block, I0, FLG3);
UML_JMPc(block, COND_Z, skip);
UML_CALLC(block, cfunc_update_flag_out<3>, this);
UML_LABEL(block, skip);
@@ -3251,13 +3240,13 @@ bool adsp21062_device::generate_opcode(drcuml_block &block, compiler_state &comp
int const compute = op_get_compute(opcode);
bool temp_pm_dreg = false;
- if (compute != 0 && pmd && desc->regout[0] & (1 << pm_dreg))
+ if (compute != 0 && pmd && desc->regout[pm_dreg])
{
UML_MOV(block, mem(&m_core->dreg_temp), REG(pm_dreg));
temp_pm_dreg = true;
}
bool temp_dm_dreg = false;
- if (compute != 0 && dmd && desc->regout[0] & (1 << dm_dreg))
+ if (compute != 0 && dmd && desc->regout[dm_dreg])
{
UML_MOV(block, mem(&m_core->dreg_temp2), REG(dm_dreg));
temp_dm_dreg = true;
@@ -3342,7 +3331,7 @@ bool adsp21062_device::generate_opcode(drcuml_block &block, compiler_state &comp
bool temp_ureg = false;
// save UREG if compute writes to it
- if (compute != 0 && ureg_is_dreg && desc->regout[0] & (1 << (ureg & 0xf)))
+ if (compute != 0 && ureg_is_dreg && desc->regout[ureg & 0xf])
{
UML_MOV(block, mem(&m_core->dreg_temp), REG(ureg & 0xf));
temp_ureg = true;
@@ -3427,7 +3416,7 @@ bool adsp21062_device::generate_opcode(drcuml_block &block, compiler_state &comp
bool temp_ureg = false;
// save UREG if compute writes to it
- if (compute != 0 && src_is_dreg && desc->regout[0] & (1 << (src_ureg & 0xf)))
+ if (compute != 0 && src_is_dreg && desc->regout[src_ureg & 0xf])
{
UML_MOV(block, mem(&m_core->dreg_temp), REG(src_ureg & 0xf));
temp_ureg = true;
@@ -3479,7 +3468,7 @@ bool adsp21062_device::generate_opcode(drcuml_block &block, compiler_state &comp
bool temp_dreg = false;
// save dreg if compute writes to it
- if (compute != 0 && BIT(desc->regout[0], dreg))
+ if (compute != 0 && desc->regout[dreg])
{
UML_MOV(block, mem(&m_core->dreg_temp), REG(dreg));
temp_dreg = true;
@@ -3586,7 +3575,7 @@ bool adsp21062_device::generate_opcode(drcuml_block &block, compiler_state &comp
bool temp_dreg = false;
// save dreg if shiftop writes to it
- if (BIT(desc->regout[0], dreg))
+ if (desc->regout[dreg])
{
UML_MOV(block, mem(&m_core->dreg_temp), REG(dreg));
temp_dreg = true;
@@ -3689,7 +3678,7 @@ bool adsp21062_device::generate_opcode(drcuml_block &block, compiler_state &comp
// DREG -> DM
bool temp_dreg = false;
// save dreg if compute writes to it
- if (BIT(desc->regout[0], dreg))
+ if (desc->regout[dreg])
{
UML_MOV(block, mem(&m_core->dreg_temp), REG(dreg));
temp_dreg = true;
@@ -3747,7 +3736,7 @@ bool adsp21062_device::generate_opcode(drcuml_block &block, compiler_state &comp
// DREG -> DM
bool temp_dreg = false;
// save dreg if compute writes to it
- if (BIT(desc->regout[0], dreg))
+ if (desc->regout[dreg])
{
UML_MOV(block, mem(&m_core->dreg_temp), REG(dreg));
temp_dreg = true;
@@ -3792,13 +3781,13 @@ bool adsp21062_device::generate_opcode(drcuml_block &block, compiler_state &comp
void adsp21062_device::generate_unimplemented_compute(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc)
{
UML_MOV(block, mem(&m_core->pc), desc->pc);
- UML_DMOV(block, mem(&m_core->arg64), desc->opptr.q[0]);
+ UML_DMOV(block, mem(&m_core->arg64), desc->opptr);
UML_CALLC(block, cfunc_unimplemented_compute, this);
}
void adsp21062_device::generate_compute(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc)
{
- uint64_t const opcode = desc->opptr.q[0];
+ uint64_t const opcode = desc->opptr;
if (op_get_compute(opcode) == 0)
return;
@@ -5635,7 +5624,7 @@ void adsp21062_device::generate_shift_imm(drcuml_block &block, compiler_state &c
case 0x13: // FDEP Rx BY <bit6>:<len6> (SE)
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.q[0]);
+ UML_DMOV(block, mem(&m_core->arg64), desc->opptr);
UML_CALLC(block, cfunc_unimplemented_shiftimm, this);
break;
@@ -5811,7 +5800,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.q[0]);
+ UML_DMOV(block, mem(&m_core->arg64), desc->opptr);
UML_CALLC(block, cfunc_unimplemented_compute, this);
return;
}
diff --git a/src/devices/cpu/sharc/sharcfe.cpp b/src/devices/cpu/sharc/sharcfe.cpp
index ff0074b02bf..6fee42cf68d 100644
--- a/src/devices/cpu/sharc/sharcfe.cpp
+++ b/src/devices/cpu/sharc/sharcfe.cpp
@@ -12,92 +12,47 @@
#include "sharcinternal.ipp"
+#include "cpu/drcfe.ipp"
-#define REG_USED(desc,x) do { (desc).regin[0] |= 1 << (x); } while(0)
-#define REG_MODIFIED(desc,x) do { (desc).regout[0] |= 1 << (x); } while(0)
-
-#define AZ_USED(desc) do { (desc).regin[0] |= 1 << 16; } while(0)
-#define AZ_MODIFIED(desc) do { (desc).regout[0] |= 1 << 16; } while(0)
-#define AV_USED(desc) do { (desc).regin[0] |= 1 << 17; } while(0)
-#define AV_MODIFIED(desc) do { (desc).regout[0] |= 1 << 17; } while(0)
-#define AN_USED(desc) do { (desc).regin[0] |= 1 << 18; } while(0)
-#define AN_MODIFIED(desc) do { (desc).regout[0] |= 1 << 18; } while(0)
-#define AC_USED(desc) do { (desc).regin[0] |= 1 << 19; } while(0)
-#define AC_MODIFIED(desc) do { (desc).regout[0] |= 1 << 19; } while(0)
-#define AS_USED(desc) do { (desc).regin[0] |= 1 << 20; } while(0)
-#define AS_MODIFIED(desc) do { (desc).regout[0] |= 1 << 20; } while(0)
-#define AI_USED(desc) do { (desc).regin[0] |= 1 << 21; } while(0)
-#define AI_MODIFIED(desc) do { (desc).regout[0] |= 1 << 21; } while(0)
-#define MN_USED(desc) do { (desc).regin[0] |= 1 << 22; } while(0)
-#define MN_MODIFIED(desc) do { (desc).regout[0] |= 1 << 22; } while(0)
-#define MV_USED(desc) do { (desc).regin[0] |= 1 << 23; } while(0)
-#define MV_MODIFIED(desc) do { (desc).regout[0] |= 1 << 23; } while(0)
-#define MU_USED(desc) do { (desc).regin[0] |= 1 << 24; } while(0)
-#define MU_MODIFIED(desc) do { (desc).regout[0] |= 1 << 24; } while(0)
-#define MI_USED(desc) do { (desc).regin[0] |= 1 << 25; } while(0)
-#define MI_MODIFIED(desc) do { (desc).regout[0] |= 1 << 25; } while(0)
-#define SV_USED(desc) do { (desc).regin[0] |= 1 << 26; } while(0)
-#define SV_MODIFIED(desc) do { (desc).regout[0] |= 1 << 26; } while(0)
-#define SZ_USED(desc) do { (desc).regin[0] |= 1 << 27; } while(0)
-#define SZ_MODIFIED(desc) do { (desc).regout[0] |= 1 << 27; } while(0)
-#define SS_USED(desc) do { (desc).regin[0] |= 1 << 28; } while(0)
-#define SS_MODIFIED(desc) do { (desc).regout[0] |= 1 << 28; } while(0)
-#define BTF_USED(desc) do { (desc).regin[0] |= 1 << 29; } while(0)
-#define BTF_MODIFIED(desc) do { (desc).regout[0] |= 1 << 29; } while(0)
-#define AF_USED(desc) do { (desc).regin[0] |= 1 << 30; } while(0)
-#define AF_MODIFIED(desc) do { (desc).regout[0] |= 1 << 30; } while(0)
-
-#define ALU_FLAGS_MODIFIED(desc) do { AZ_MODIFIED(desc);AN_MODIFIED(desc);AV_MODIFIED(desc);AC_MODIFIED(desc);AS_MODIFIED(desc);AI_MODIFIED(desc); } while(0)
-#define MULT_FLAGS_MODIFIED(desc) do { MN_MODIFIED(desc);MV_MODIFIED(desc);MU_MODIFIED(desc);MI_MODIFIED(desc); } while(0)
-#define SHIFT_FLAGS_MODIFIED(desc) do { SZ_MODIFIED(desc);SV_MODIFIED(desc);SS_MODIFIED(desc); } while(0)
-
-
-#define PM_I_USED(desc,x) do { (desc).regin[1] |= 1 << (x); } while(0)
-#define PM_I_MODIFIED(desc,x) do { (desc).regout[1] |= 1 << (x); } while(0)
-#define PM_M_USED(desc,x) do { (desc).regin[1] |= 1 << ((x) + 8); } while(0)
-#define PM_M_MODIFIED(desc,x) do { (desc).regout[1] |= 1 << ((x) + 8); } while(0)
-#define PM_B_USED(desc,x) do { (desc).regin[1] |= 1 << ((x) + 16); } while(0)
-#define PM_B_MODIFIED(desc,x) do { (desc).regout[1] |= 1 << ((x) + 16); } while(0)
-#define PM_L_USED(desc,x) do { (desc).regin[1] |= 1 << ((x) + 24); } while(0)
-#define PM_L_MODIFIED(desc,x) do { (desc).regout[1] |= 1 << ((x) + 24); } while(0)
-
-#define DM_I_USED(desc,x) do { (desc).regin[2] |= 1 << (x); } while(0)
-#define DM_I_MODIFIED(desc,x) do { (desc).regout[2] |= 1 << (x); } while(0)
-#define DM_M_USED(desc,x) do { (desc).regin[2] |= 1 << ((x) + 8); } while(0)
-#define DM_M_MODIFIED(desc,x) do { (desc).regout[2] |= 1 << ((x) + 8); } while(0)
-#define DM_B_USED(desc,x) do { (desc).regin[2] |= 1 << ((x) + 16); } while(0)
-#define DM_B_MODIFIED(desc,x) do { (desc).regout[2] |= 1 << ((x) + 16); } while(0)
-#define DM_L_USED(desc,x) do { (desc).regin[2] |= 1 << ((x) + 24); } while(0)
-#define DM_L_MODIFIED(desc,x) do { (desc).regout[2] |= 1 << ((x) + 24); } while(0)
-
-
-sharc_frontend::sharc_frontend(adsp21062_device *sharc, uint32_t window_start, uint32_t window_end, uint32_t max_sequence)
- : drc_frontend(*sharc, window_start, window_end, max_sequence)
+
+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)
, m_sharc(sharc)
{
m_loopmap = std::make_unique<LOOP_ENTRY[]>(0x20000);
}
+adsp21062_device::frontend::~frontend()
+{
+}
-void sharc_frontend::flush()
+adsp21062_device::opcode_desc const *adsp21062_device::frontend::describe_code(offs_t startpc)
{
- LOOP_ENTRY* map = m_loopmap.get();
+ return do_describe_code(
+ [this] (opcode_desc &desc, opcode_desc const *prev) { return describe(desc, prev); },
+ startpc);
+}
+
+
+void adsp21062_device::frontend::flush()
+{
+ LOOP_ENTRY *map = m_loopmap.get();
memset(map, 0, sizeof(LOOP_ENTRY) * 0x20000);
}
-void sharc_frontend::add_loop_entry(uint32_t pc, uint8_t type, uint32_t userflags)
+void adsp21062_device::frontend::add_loop_entry(uint32_t pc, uint8_t type, opcode_desc::extra_flags const &userflags)
{
uint32_t l2 = pc >> 17;
uint32_t l1 = pc & 0x1ffff;
if (l2 != 0x1)
- fatalerror("sharc_frontend::add_loop_entry: PC = %08X", pc);
+ fatalerror("adsp21062_device::frontend::add_loop_entry: PC = %08X", pc);
LOOP_ENTRY* map = m_loopmap.get();
uint32_t current_type = map[l1].entrytype;
- uint32_t current_userflags = map[l1].userflags;
+ opcode_desc::extra_flags current_userflags = map[l1].userflags;
current_type |= type;
current_userflags |= userflags;
@@ -106,28 +61,29 @@ void sharc_frontend::add_loop_entry(uint32_t pc, uint8_t type, uint32_t userflag
map[l1].userflags = current_userflags;
}
-void sharc_frontend::insert_loop(const LOOP_DESCRIPTOR &loopdesc)
+void adsp21062_device::frontend::insert_loop(const LOOP_DESCRIPTOR &loopdesc)
{
add_loop_entry(loopdesc.start_pc, LOOP_ENTRY_START, 0);
add_loop_entry(loopdesc.end_pc, LOOP_ENTRY_EVALUATION, 0);
if (loopdesc.astat_check_pc != 0xffffffff)
{
uint32_t flags = m_sharc->do_condition_astat_bits(loopdesc.condition);
- uint32_t userflags = 0;
- if (flags & adsp21062_device::ASTAT_FLAGS::AZ) { userflags |= OP_USERFLAG_ASTAT_DELAY_COPY_AZ; }
- if (flags & adsp21062_device::ASTAT_FLAGS::AN) { userflags |= OP_USERFLAG_ASTAT_DELAY_COPY_AN; }
- if (flags & adsp21062_device::ASTAT_FLAGS::AV) { userflags |= OP_USERFLAG_ASTAT_DELAY_COPY_AV; }
- if (flags & adsp21062_device::ASTAT_FLAGS::AC) { userflags |= OP_USERFLAG_ASTAT_DELAY_COPY_AC; }
- if (flags & adsp21062_device::ASTAT_FLAGS::MN) { userflags |= OP_USERFLAG_ASTAT_DELAY_COPY_MN; }
- if (flags & adsp21062_device::ASTAT_FLAGS::MV) { userflags |= OP_USERFLAG_ASTAT_DELAY_COPY_MV; }
- if (flags & adsp21062_device::ASTAT_FLAGS::SV) { userflags |= OP_USERFLAG_ASTAT_DELAY_COPY_SV; }
- if (flags & adsp21062_device::ASTAT_FLAGS::SZ) { userflags |= OP_USERFLAG_ASTAT_DELAY_COPY_SZ; }
- if (flags & adsp21062_device::ASTAT_FLAGS::BTF) { userflags |= OP_USERFLAG_ASTAT_DELAY_COPY_BTF; }
+ 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 & 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 & 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); }
add_loop_entry(loopdesc.astat_check_pc, LOOP_ENTRY_ASTAT_CHECK, userflags);
}
}
-bool sharc_frontend::is_loop_evaluation(uint32_t pc)
+bool adsp21062_device::frontend::is_loop_evaluation(uint32_t pc)
{
uint32_t l2 = pc >> 17;
uint32_t l1 = pc & 0x1ffff;
@@ -142,7 +98,7 @@ bool sharc_frontend::is_loop_evaluation(uint32_t pc)
return false;
}
-bool sharc_frontend::is_loop_start(uint32_t pc)
+bool adsp21062_device::frontend::is_loop_start(uint32_t pc)
{
uint32_t l2 = pc >> 17;
uint32_t l1 = pc & 0x1ffff;
@@ -157,7 +113,7 @@ bool sharc_frontend::is_loop_start(uint32_t pc)
return false;
}
-bool sharc_frontend::is_astat_delay_check(uint32_t pc)
+bool adsp21062_device::frontend::is_astat_delay_check(uint32_t pc)
{
uint32_t l2 = pc >> 17;
uint32_t l1 = pc & 0x1ffff;
@@ -173,39 +129,38 @@ bool sharc_frontend::is_astat_delay_check(uint32_t pc)
}
-bool sharc_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
+bool adsp21062_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev)
{
- uint64_t opcode = desc.opptr.q[0] = m_sharc->pm_read48(desc.physpc);
+ uint64_t opcode = desc.opptr = m_sharc->pm_read48(desc.pc);
desc.length = 1;
- desc.cycles = 1;
// handle looping
if (is_astat_delay_check(desc.pc))
{
- LOOP_ENTRY* map = m_loopmap.get();
+ LOOP_ENTRY *map = m_loopmap.get();
int index = desc.pc & 0x1ffff;
- desc.userflags |= map[index].userflags;
- if (map[index].userflags & OP_USERFLAG_ASTAT_DELAY_COPY_AZ) { AZ_USED(desc); }
- if (map[index].userflags & OP_USERFLAG_ASTAT_DELAY_COPY_AN) { AN_USED(desc); }
- if (map[index].userflags & OP_USERFLAG_ASTAT_DELAY_COPY_AV) { AV_USED(desc); }
- if (map[index].userflags & OP_USERFLAG_ASTAT_DELAY_COPY_AC) { AC_USED(desc); }
- if (map[index].userflags & OP_USERFLAG_ASTAT_DELAY_COPY_MN) { MN_USED(desc); }
- if (map[index].userflags & OP_USERFLAG_ASTAT_DELAY_COPY_MV) { MV_USED(desc); }
- if (map[index].userflags & OP_USERFLAG_ASTAT_DELAY_COPY_SV) { SV_USED(desc); }
- if (map[index].userflags & OP_USERFLAG_ASTAT_DELAY_COPY_SZ) { SZ_USED(desc); }
- if (map[index].userflags & OP_USERFLAG_ASTAT_DELAY_COPY_BTF) { BTF_USED(desc); }
+ desc.set_extra_flags(map[index].userflags);
+ if (map[index].userflags[opcode_desc::ASTAT_DELAY_COPY_AZ]) { desc.set_az_used(); }
+ if (map[index].userflags[opcode_desc::ASTAT_DELAY_COPY_AN]) { desc.set_an_used(); }
+ if (map[index].userflags[opcode_desc::ASTAT_DELAY_COPY_AV]) { desc.set_av_used(); }
+ if (map[index].userflags[opcode_desc::ASTAT_DELAY_COPY_AC]) { desc.set_ac_used(); }
+ if (map[index].userflags[opcode_desc::ASTAT_DELAY_COPY_MN]) { desc.set_mn_used(); }
+ if (map[index].userflags[opcode_desc::ASTAT_DELAY_COPY_MV]) { desc.set_mv_used(); }
+ if (map[index].userflags[opcode_desc::ASTAT_DELAY_COPY_SV]) { desc.set_sv_used(); }
+ if (map[index].userflags[opcode_desc::ASTAT_DELAY_COPY_SZ]) { desc.set_sz_used(); }
+ if (map[index].userflags[opcode_desc::ASTAT_DELAY_COPY_BTF]) { desc.set_btf_used(); }
}
if (is_loop_start(desc.pc))
{
- desc.flags |= OPFLAG_IS_BRANCH_TARGET;
+ desc.set_is_branch_target();
}
if (is_loop_evaluation(desc.pc))
{
- desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
- desc.userflags |= OP_USERFLAG_LOOP;
+ desc.set_is_conditional_branch();
+ desc.set_loop();
}
@@ -220,7 +175,7 @@ bool sharc_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
if (opcode & 0x008000000000U)
{
// IDLE
- desc.flags |= OPFLAG_END_SEQUENCE;
+ desc.set_end_sequence();
}
else
{
@@ -267,16 +222,16 @@ bool sharc_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
if (g)
{
// PM
- PM_I_USED(desc, i);
- PM_I_MODIFIED(desc, i);
- PM_M_USED(desc, m);
+ desc.set_pm_i_used(i);
+ desc.set_pm_i_modified(i);
+ desc.set_pm_m_used(m);
}
else
{
// DM
- DM_I_USED(desc, i);
- DM_I_MODIFIED(desc, i);
- DM_M_USED(desc, m);
+ desc.set_dm_i_used(i);
+ desc.set_dm_i_modified(i);
+ desc.set_dm_m_used(m);
}
break;
}
@@ -289,16 +244,21 @@ bool sharc_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
uint32_t const address = opcode & 0xffffff;
if (m_sharc->if_condition_always_true(cond))
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ {
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
+ }
else
- desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+ {
+ desc.set_is_conditional_branch();
+ }
describe_if_condition(desc, cond);
desc.targetpc = address;
- desc.delayslots = (j) ? 2 : 0;
+ desc.delayslots = j ? 2 : 0;
- desc.userflags |= (b) ? OP_USERFLAG_CALL : 0;
+ if (b) desc.set_call();
break;
}
@@ -310,16 +270,21 @@ bool sharc_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
uint32_t const address = opcode & 0xffffff;
if (m_sharc->if_condition_always_true(cond))
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ {
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
+ }
else
- desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+ {
+ desc.set_is_conditional_branch();
+ }
describe_if_condition(desc, cond);
desc.targetpc = desc.pc + util::sext(address, 24);
- desc.delayslots = (j) ? 2 : 0;
+ desc.delayslots = j ? 2 : 0;
- desc.userflags |= (b) ? OP_USERFLAG_CALL : 0;
+ if (b) desc.set_call();
break;
}
@@ -335,19 +300,24 @@ bool sharc_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
return false;
if (m_sharc->if_condition_always_true(cond))
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ {
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
+ }
else
- desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+ {
+ desc.set_is_conditional_branch();
+ }
describe_if_condition(desc, cond);
- PM_I_USED(desc, pmi);
- PM_M_USED(desc, pmm);
+ desc.set_pm_i_used(pmi);
+ desc.set_pm_m_used(pmm);
desc.targetpc = BRANCH_TARGET_DYNAMIC;
- desc.delayslots = (j) ? 2 : 0;
+ desc.delayslots = j ? 2 : 0;
- desc.userflags |= (b) ? OP_USERFLAG_CALL : 0;
+ if (b) desc.set_call();
break;
}
@@ -361,16 +331,21 @@ bool sharc_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
return false;
if (m_sharc->if_condition_always_true(cond))
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ {
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
+ }
else
- desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+ {
+ desc.set_is_conditional_branch();
+ }
describe_if_condition(desc, cond);
desc.targetpc = desc.pc + op_get_reladdr(opcode);
- desc.delayslots = (j) ? 2 : 0;
+ desc.delayslots = j ? 2 : 0;
- desc.userflags |= (b) ? OP_USERFLAG_CALL : 0;
+ if (b) desc.set_call();
break;
}
@@ -383,14 +358,19 @@ bool sharc_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
return false;
if (m_sharc->if_condition_always_true(cond))
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ {
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
+ }
else
- desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+ {
+ desc.set_is_conditional_branch();
+ }
describe_if_condition(desc, cond);
desc.targetpc = BRANCH_TARGET_DYNAMIC;
- desc.delayslots = (j) ? 2 : 0;
+ desc.delayslots = j ? 2 : 0;
break;
}
@@ -403,14 +383,19 @@ bool sharc_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
return false;
if (m_sharc->if_condition_always_true(cond))
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ {
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
+ }
else
- desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+ {
+ desc.set_is_conditional_branch();
+ }
describe_if_condition(desc, cond);
desc.targetpc = BRANCH_TARGET_DYNAMIC;
- desc.delayslots = (j) ? 2 : 0;
+ desc.delayslots = j ? 2 : 0;
break;
}
@@ -473,7 +458,6 @@ bool sharc_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
else
loop.astat_check_pc = loop.end_pc;
-
insert_loop(loop);
break;
}
@@ -497,13 +481,13 @@ bool sharc_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
{
if (!describe_ureg_access(desc, ureg, UREG_READ))
return false;
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_writes_memory();
}
else
{
if (!describe_ureg_access(desc, ureg, UREG_WRITE))
return false;
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_reads_memory();
}
break;
}
@@ -518,79 +502,98 @@ bool sharc_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
{
case 0: // SET
case 1: // CLEAR
+ if (sreg == 0x7c) // ASTAT
+ {
+ if (data & AZ) desc.set_az_modified();
+ if (data & AV) desc.set_av_modified();
+ if (data & AN) desc.set_an_modified();
+ if (data & AC) desc.set_ac_modified();
+ if (data & AS) desc.set_as_modified();
+ if (data & AI) desc.set_ai_modified();
+ if (data & MN) desc.set_mn_modified();
+ if (data & MV) desc.set_mv_modified();
+ if (data & MU) desc.set_mu_modified();
+ if (data & MI) desc.set_mi_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 & adsp21062_device::AZ)
+ if (data & AZ)
{
- AZ_USED(desc); AZ_MODIFIED(desc);
+ desc.set_az_used(); desc.set_az_modified();
}
- if (data & adsp21062_device::AV)
+ if (data & AV)
{
- AV_USED(desc); AV_MODIFIED(desc);
+ desc.set_av_used(); desc.set_av_modified();
}
- if (data & adsp21062_device::AN)
+ if (data & AN)
{
- AN_USED(desc); AN_MODIFIED(desc);
+ desc.set_an_used(); desc.set_an_modified();
}
- if (data & adsp21062_device::AC)
+ if (data & AC)
{
- AC_USED(desc); AC_MODIFIED(desc);
+ desc.set_ac_used(); desc.set_ac_modified();
}
- if (data & adsp21062_device::AS)
+ if (data & AS)
{
- AS_USED(desc); AS_MODIFIED(desc);
+ desc.set_as_used(); desc.set_as_modified();
}
- if (data & adsp21062_device::AI)
+ if (data & AI)
{
- AI_USED(desc); AI_MODIFIED(desc);
+ desc.set_ai_used(); desc.set_ai_modified();
}
- if (data & adsp21062_device::MN)
+ if (data & MN)
{
- MN_USED(desc); MN_MODIFIED(desc);
+ desc.set_mn_used(); desc.set_mn_modified();
}
- if (data & adsp21062_device::MV)
+ if (data & MV)
{
- MV_USED(desc); MV_MODIFIED(desc);
+ desc.set_mv_used(); desc.set_mv_modified();
}
- if (data & adsp21062_device::MU)
+ if (data & MU)
{
- MU_USED(desc); MU_MODIFIED(desc);
+ desc.set_mu_used(); desc.set_mu_modified();
}
- if (data & adsp21062_device::MI)
+ if (data & MI)
{
- MI_USED(desc); MI_MODIFIED(desc);
+ desc.set_mi_used(); desc.set_mi_modified();
}
- if (data & adsp21062_device::SV)
+ if (data & SV)
{
- SV_USED(desc); SV_MODIFIED(desc);
+ desc.set_sv_used(); desc.set_sv_modified();
}
- if (data & adsp21062_device::SZ)
+ if (data & SZ)
{
- SZ_USED(desc); SZ_MODIFIED(desc);
+ desc.set_sz_used(); desc.set_sz_modified();
}
- if (data & adsp21062_device::SS)
+ if (data & SS)
{
- SS_USED(desc); SS_MODIFIED(desc);
+ desc.set_ss_used(); desc.set_ss_modified();
}
- if (data & adsp21062_device::BTF)
+ if (data & BTF)
{
- BTF_USED(desc); BTF_MODIFIED(desc);
+ desc.set_btf_used(); desc.set_btf_modified();
}
- if (data & adsp21062_device::AF)
+ if (data & AF)
{
- AF_USED(desc); AF_MODIFIED(desc);
+ desc.set_af_used(); desc.set_af_modified();
}
}
break;
case 4: // TEST
case 5: // XOR
- BTF_MODIFIED(desc);
+ desc.set_btf_modified();
break;
default:
- fatalerror("sharc_frontend::describe: system reg bit manipulation %d", bop);
+ fatalerror("adsp21062_device::frontend::describe: system reg bit manipulation %d", bop);
return false;
}
break;
@@ -600,7 +603,7 @@ bool sharc_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
{
if (opcode & 0x008000000000U) // bit reverse
{
- fatalerror("sharc_frontend::describe: bit reverse unimplemented");
+ fatalerror("adsp21062_device::frontend::describe: bit reverse unimplemented");
}
else // modify
{
@@ -608,9 +611,9 @@ bool sharc_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
int const i = (opcode >> 32) & 0x7;
if (g)
- PM_I_USED(desc, i);
+ desc.set_pm_i_used(i);
else
- DM_I_USED(desc, i);
+ desc.set_dm_i_used(i);
}
break;
}
@@ -619,15 +622,15 @@ bool sharc_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
break;
case 0x18: // cjump |000|11000|
- fatalerror("sharc_frontend::describe: cjump unimplemented");
+ fatalerror("adsp21062_device::frontend::describe: cjump unimplemented");
break;
case 0x19: // rframe |000|11001|
- fatalerror("sharc_frontend::describe: rframe unimplemented");
+ fatalerror("adsp21062_device::frontend::describe: rframe unimplemented");
break;
default:
- fatalerror("sharc_frontend::describe: unknown subop %02X in opcode %04X%08X", subop, (uint16_t)(opcode >> 32), (uint32_t)(opcode));
+ fatalerror("adsp21062_device::frontend::describe: unknown subop %02X in opcode %04X%08X", subop, (uint16_t)(opcode >> 32), (uint32_t)(opcode));
return false;
}
break;
@@ -647,34 +650,34 @@ bool sharc_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
int const pmd = (opcode >> 37) & 0x1;
int const dmd = (opcode >> 44) & 0x1;
- PM_I_USED(desc, pmi);
- PM_I_MODIFIED(desc, pmi);
- PM_M_USED(desc, pmm);
+ desc.set_pm_i_used(pmi);
+ desc.set_pm_i_modified(pmi);
+ desc.set_pm_m_used(pmm);
if (pmd)
{
- REG_USED(desc, pm_dreg);
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_reg_used(pm_dreg);
+ desc.set_writes_memory();
}
else
{
- REG_MODIFIED(desc, pm_dreg);
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_reg_modified(pm_dreg);
+ desc.set_reads_memory();
}
- DM_I_USED(desc, dmi);
- DM_I_MODIFIED(desc, dmi);
- DM_M_USED(desc, dmm);
+ desc.set_dm_i_used(dmi);
+ desc.set_dm_i_modified(dmi);
+ desc.set_dm_m_used(dmm);
if (dmd)
{
- REG_USED(desc, dm_dreg);
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_reg_used(dm_dreg);
+ desc.set_writes_memory();
}
else
{
- REG_MODIFIED(desc, dm_dreg);
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_reg_modified(dm_dreg);
+ desc.set_reads_memory();
}
break;
}
@@ -697,26 +700,26 @@ bool sharc_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
{
if (!describe_ureg_access(desc, ureg, UREG_READ))
return false;
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_writes_memory();
}
else
{
if (!describe_ureg_access(desc, ureg, UREG_WRITE))
return false;
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_writes_memory();
}
if (g)
{
// PM
- PM_I_USED(desc, i);
- PM_M_USED(desc, m);
+ desc.set_pm_i_used(i);
+ desc.set_pm_m_used(m);
}
else
{
// DM
- DM_I_USED(desc, i);
- DM_M_USED(desc, m);
+ desc.set_dm_i_used(i);
+ desc.set_dm_m_used(m);
}
break;
@@ -753,33 +756,33 @@ bool sharc_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
if (d)
{
- REG_USED(desc, dreg);
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_reg_used(dreg);
+ desc.set_writes_memory();
}
else
{
- REG_MODIFIED(desc, dreg);
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_reg_modified(dreg);
+ desc.set_reads_memory();
}
if (g)
{
// PM
- PM_I_USED(desc, i);
+ desc.set_pm_i_used(i);
if (u) // post-modify with update
{
- PM_I_MODIFIED(desc, i);
+ desc.set_pm_i_modified(i);
}
}
else
{
// DM
- DM_I_USED(desc, i);
+ desc.set_dm_i_used(i);
if (u) // post-modify with update
{
- DM_I_MODIFIED(desc, i);
+ desc.set_dm_i_modified(i);
}
}
}
@@ -794,21 +797,21 @@ bool sharc_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
int const m = (opcode >> 38) & 0x7;
int const g = (opcode >> 37) & 0x1;
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_writes_memory();
if (g)
{
// PM
- PM_I_USED(desc, i);
- PM_I_MODIFIED(desc, i);
- PM_M_USED(desc, m);
+ desc.set_pm_i_used(i);
+ desc.set_pm_i_modified(i);
+ desc.set_pm_m_used(m);
}
else
{
// DM
- DM_I_USED(desc, i);
- DM_I_MODIFIED(desc, i);
- DM_M_USED(desc, m);
+ desc.set_dm_i_used(i);
+ desc.set_dm_i_modified(i);
+ desc.set_dm_m_used(m);
}
}
else // immediate shift / dreg <-> DM|PM |100|0|
@@ -830,28 +833,28 @@ bool sharc_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
if (d)
{
- REG_USED(desc, dreg);
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_reg_used(dreg);
+ desc.set_writes_memory();
}
else
{
- REG_MODIFIED(desc, dreg);
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_reg_modified(dreg);
+ desc.set_reads_memory();
}
if (g)
{
// PM
- PM_I_USED(desc, i);
- PM_I_MODIFIED(desc, i);
- PM_M_USED(desc, m);
+ desc.set_pm_i_used(i);
+ desc.set_pm_i_modified(i);
+ desc.set_pm_m_used(m);
}
else
{
// DM
- DM_I_USED(desc, i);
- DM_I_MODIFIED(desc, i);
- DM_M_USED(desc, m);
+ desc.set_dm_i_used(i);
+ desc.set_dm_i_modified(i);
+ desc.set_dm_m_used(m);
}
}
break;
@@ -868,19 +871,19 @@ bool sharc_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
{
if (!describe_ureg_access(desc, ureg, UREG_READ))
return false;
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_writes_memory();
}
else
{
if (!describe_ureg_access(desc, ureg, UREG_WRITE))
return false;
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_reads_memory();
}
if (g)
- PM_I_USED(desc, i);
+ desc.set_pm_i_used(i);
else
- DM_I_USED(desc, i);
+ desc.set_dm_i_used(i);
break;
}
@@ -898,27 +901,32 @@ bool sharc_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
return false;
if (m_sharc->if_condition_always_true(cond))
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ {
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
+ }
else
- desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+ {
+ desc.set_is_conditional_branch();
+ }
describe_if_condition(desc, cond);
- PM_I_USED(desc, pmi);
- PM_M_USED(desc, pmm);
- DM_I_USED(desc, dmi);
- DM_I_MODIFIED(desc, dmi);
- DM_M_USED(desc, dmm);
+ desc.set_pm_i_used(pmi);
+ desc.set_pm_m_used(pmm);
+ desc.set_dm_i_used(dmi);
+ desc.set_dm_i_modified(dmi);
+ desc.set_dm_m_used(dmm);
if (d)
{
- REG_USED(desc, dreg);
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_reg_used(dreg);
+ desc.set_writes_memory();
}
else
{
- REG_MODIFIED(desc, dreg);
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_reg_modified(dreg);
+ desc.set_reads_memory();
}
desc.targetpc = BRANCH_TARGET_DYNAMIC;
@@ -938,25 +946,30 @@ bool sharc_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
return false;
if (m_sharc->if_condition_always_true(cond))
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ {
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
+ }
else
- desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH;
+ {
+ desc.set_is_conditional_branch();
+ }
describe_if_condition(desc, cond);
- DM_I_USED(desc, dmi);
- DM_I_MODIFIED(desc, dmi);
- DM_M_USED(desc, dmm);
+ desc.set_dm_i_used(dmi);
+ desc.set_dm_i_modified(dmi);
+ desc.set_dm_m_used(dmm);
if (d)
{
- REG_USED(desc, dreg);
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_reg_used(dreg);
+ desc.set_writes_memory();
}
else
{
- REG_MODIFIED(desc, dreg);
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_reg_modified(dreg);
+ desc.set_reads_memory();
}
desc.targetpc = desc.pc + op_get_reladdr(opcode);
@@ -968,7 +981,7 @@ bool sharc_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
return true;
}
-bool sharc_frontend::describe_compute(opcode_desc &desc, uint64_t opcode)
+bool adsp21062_device::frontend::describe_compute(opcode_desc &desc, uint64_t opcode)
{
// skip if no-op
if ((opcode & 0x7fffff) == 0)
@@ -993,80 +1006,80 @@ bool sharc_frontend::describe_compute(opcode_desc &desc, uint64_t opcode)
switch (multiop)
{
case 0x00: // Rn = MRxx
- REG_MODIFIED(desc, rn);
+ desc.set_reg_modified(rn);
break;
case 0x01: // MRxx = Rn
- REG_USED(desc, rn);
+ desc.set_reg_used(rn);
break;
case 0x07: // Ra = Rx + Ry, Rs = Rx - Ry
case 0x0f: // Fa = Fx + Fy, Fs = Fx - Fy
- REG_USED(desc, rx);
- REG_USED(desc, ry);
- REG_MODIFIED(desc, ra);
- REG_MODIFIED(desc, rs);
- ALU_FLAGS_MODIFIED(desc);
+ desc.set_reg_used(rx);
+ desc.set_reg_used(ry);
+ desc.set_reg_modified(ra);
+ desc.set_reg_modified(rs);
+ desc.set_alu_flags_modified();
break;
case 0x04: // Rm = R3-0 * R7-4 (SSFR), Ra = R11-8 + R15-12
case 0x05: // Rm = R3-0 * R7-4 (SSFR), Ra = R11-8 - R15-12
case 0x06: // Rm = R3-0 * R7-4 (SSFR), Ra = (R11-8 + R15-12) / 2
- REG_USED(desc, fxm);
- REG_USED(desc, fym);
- REG_USED(desc, fxa);
- REG_USED(desc, fya);
- REG_MODIFIED(desc, fm);
- REG_MODIFIED(desc, fa);
- ALU_FLAGS_MODIFIED(desc);
- MULT_FLAGS_MODIFIED(desc);
+ desc.set_reg_used(fxm);
+ desc.set_reg_used(fym);
+ desc.set_reg_used(fxa);
+ desc.set_reg_used(fya);
+ desc.set_reg_modified(fm);
+ desc.set_reg_modified(fa);
+ desc.set_alu_flags_modified();
+ desc.set_mult_flags_modified();
break;
case 0x08: // MRF = MRF + R3-0 * R7-4 (SSF), Ra = R11-8 + R15-12
case 0x09: // MRF = MRF + R3-0 * R7-4 (SSF), Ra = R11-8 - R15-12
case 0x0a: // MRF = MRF + R3-0 * R7-4 (SSF), Ra = (R11-8 + R15-12) / 2
- REG_USED(desc, fxm);
- REG_USED(desc, fym);
- REG_USED(desc, fxa);
- REG_USED(desc, fya);
- ALU_FLAGS_MODIFIED(desc);
- MULT_FLAGS_MODIFIED(desc);
+ desc.set_reg_used(fxm);
+ desc.set_reg_used(fym);
+ desc.set_reg_used(fxa);
+ desc.set_reg_used(fya);
+ desc.set_alu_flags_modified();
+ desc.set_mult_flags_modified();
break;
case 0x0c: // Rm = MRF + R3-0 * R7-4 (SSFR), Ra = R11-8 + R15-12
case 0x0d: // Rm = MRF + R3-0 * R7-4 (SSFR), Ra = R11-8 - R15-12
case 0x0e: // Rm = MRF + R3-0 * R7-4 (SSFR), Ra = (R11-8 + R15-12) / 2
- REG_USED(desc, fxm);
- REG_USED(desc, fym);
- REG_USED(desc, fxa);
- REG_USED(desc, fya);
- REG_MODIFIED(desc, fm);
- REG_MODIFIED(desc, fa);
- ALU_FLAGS_MODIFIED(desc);
- MULT_FLAGS_MODIFIED(desc);
+ desc.set_reg_used(fxm);
+ desc.set_reg_used(fym);
+ desc.set_reg_used(fxa);
+ desc.set_reg_used(fya);
+ desc.set_reg_modified(fm);
+ desc.set_reg_modified(fa);
+ desc.set_alu_flags_modified();
+ desc.set_mult_flags_modified();
break;
case 0x10: // MRF = MRF - R3-0 * R7-4 (SSF), Ra = R11-8 + R15-12
case 0x11: // MRF = MRF - R3-0 * R7-4 (SSF), Ra = R11-8 - R15-12
case 0x12: // MRF = MRF - R3-0 * R7-4 (SSF), Ra = (R11-8 + R15-12) / 2
- REG_USED(desc, fxm);
- REG_USED(desc, fym);
- REG_USED(desc, fxa);
- REG_USED(desc, fya);
- ALU_FLAGS_MODIFIED(desc);
- MULT_FLAGS_MODIFIED(desc);
+ desc.set_reg_used(fxm);
+ desc.set_reg_used(fym);
+ desc.set_reg_used(fxa);
+ desc.set_reg_used(fya);
+ desc.set_alu_flags_modified();
+ desc.set_mult_flags_modified();
break;
case 0x14: // Rm = MRF - R3-0 * R7-4 (SSFR), Ra = R11-8 + R15-12
case 0x15: // Rm = MRF - R3-0 * R7-4 (SSFR), Ra = R11-8 - R15-12
case 0x16: // Rm = MRF - R3-0 * R7-4 (SSFR), Ra = (R11-8 + R15-12) / 2
- REG_USED(desc, fxm);
- REG_USED(desc, fym);
- REG_USED(desc, fxa);
- REG_USED(desc, fya);
- REG_MODIFIED(desc, fm);
- REG_MODIFIED(desc, fa);
- ALU_FLAGS_MODIFIED(desc);
- MULT_FLAGS_MODIFIED(desc);
+ desc.set_reg_used(fxm);
+ desc.set_reg_used(fym);
+ desc.set_reg_used(fxa);
+ desc.set_reg_used(fya);
+ desc.set_reg_modified(fm);
+ desc.set_reg_modified(fa);
+ desc.set_alu_flags_modified();
+ desc.set_mult_flags_modified();
break;
case 0x18: // Fm = F3-0 * F7-4, Fa = F11-8 + F15-12
@@ -1076,56 +1089,56 @@ bool sharc_frontend::describe_compute(opcode_desc &desc, uint64_t opcode)
case 0x1c: // Fm = F3-0 * F7-4, Fa = (F11-8 + F15-12) / 2
case 0x1e: // Fm = F3-0 * F7-4, Fa = MAX(F11-8, F15-12)
case 0x1f: // Fm = F3-0 * F7-4, Fa = MIN(F11-8, F15-12)
- REG_USED(desc, fxm);
- REG_USED(desc, fym);
- REG_USED(desc, fxa);
- REG_USED(desc, fya);
- REG_MODIFIED(desc, fm);
- REG_MODIFIED(desc, fa);
- ALU_FLAGS_MODIFIED(desc);
- MULT_FLAGS_MODIFIED(desc);
+ desc.set_reg_used(fxm);
+ desc.set_reg_used(fym);
+ desc.set_reg_used(fxa);
+ desc.set_reg_used(fya);
+ desc.set_reg_modified(fm);
+ desc.set_reg_modified(fa);
+ desc.set_alu_flags_modified();
+ desc.set_mult_flags_modified();
break;
case 0x1d: // Fm = F3-0 * F7-4, Fa = ABS F11-8
- REG_USED(desc, fxm);
- REG_USED(desc, fym);
- REG_USED(desc, fxa);
- REG_MODIFIED(desc, fm);
- REG_MODIFIED(desc, fa);
- ALU_FLAGS_MODIFIED(desc);
- MULT_FLAGS_MODIFIED(desc);
+ desc.set_reg_used(fxm);
+ desc.set_reg_used(fym);
+ desc.set_reg_used(fxa);
+ desc.set_reg_modified(fm);
+ desc.set_reg_modified(fa);
+ desc.set_alu_flags_modified();
+ desc.set_mult_flags_modified();
break;
case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
// Rm = R3-0 * R7-4 (SSFR), Ra = R11-8 + R15-12, Rs = R11-8 - R15-12
- REG_USED(desc, fxm);
- REG_USED(desc, fym);
- REG_USED(desc, fxa);
- REG_USED(desc, fya);
- REG_MODIFIED(desc, fm);
- REG_MODIFIED(desc, fa);
- REG_MODIFIED(desc, (opcode >> 16) & 0xf);
- ALU_FLAGS_MODIFIED(desc);
- MULT_FLAGS_MODIFIED(desc);
+ desc.set_reg_used(fxm);
+ desc.set_reg_used(fym);
+ desc.set_reg_used(fxa);
+ desc.set_reg_used(fya);
+ desc.set_reg_modified(fm);
+ desc.set_reg_modified(fa);
+ desc.set_reg_modified((opcode >> 16) & 0xf);
+ desc.set_alu_flags_modified();
+ desc.set_mult_flags_modified();
break;
case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:
// Fm = F3-0 * F7-4, Fa = F11-8 + F15-12, Fs = F11-8 - F15-12
- REG_USED(desc, fxm);
- REG_USED(desc, fym);
- REG_USED(desc, fxa);
- REG_USED(desc, fya);
- REG_MODIFIED(desc, fm);
- REG_MODIFIED(desc, fa);
- REG_MODIFIED(desc, (opcode >> 16) & 0xf);
- ALU_FLAGS_MODIFIED(desc);
- MULT_FLAGS_MODIFIED(desc);
+ desc.set_reg_used(fxm);
+ desc.set_reg_used(fym);
+ desc.set_reg_used(fxa);
+ desc.set_reg_used(fya);
+ desc.set_reg_modified(fm);
+ desc.set_reg_modified(fa);
+ desc.set_reg_modified((opcode >> 16) & 0xf);
+ desc.set_alu_flags_modified();
+ desc.set_mult_flags_modified();
break;
default:
- fatalerror("sharc_frontend::describe_compute: unknown multiop %02X in opcode %04X%08X at %08X", multiop, (uint16_t)(opcode >> 32), (uint32_t)(opcode), desc.pc);
+ fatalerror("adsp21062_device::frontend::describe_compute: unknown multiop %02X in opcode %04X%08X at %08X", multiop, (uint16_t)(opcode >> 32), (uint32_t)(opcode), desc.pc);
return false;
}
}
@@ -1161,28 +1174,28 @@ bool sharc_frontend::describe_compute(opcode_desc &desc, uint64_t opcode)
case 0xe2: // Fn = MAX(Fx, Fy)
case 0xe3: // Fn = CLIP Fx BY Fy
case 0xe0: // Fn = Fx COPYSIGN Fy
- REG_USED(desc, rx);
- REG_USED(desc, ry);
- REG_MODIFIED(desc, rn);
- ALU_FLAGS_MODIFIED(desc);
+ desc.set_reg_used(rx);
+ desc.set_reg_used(ry);
+ desc.set_reg_modified(rn);
+ desc.set_alu_flags_modified();
break;
case 0x05: // Rn = Rx + Ry + CI
case 0x06: // Rn = Rx - Ry + CI - 1
case 0x25: // Rn = Rx + CI
case 0x26: // Rn = Rx + CI - 1
- REG_USED(desc, rx);
- REG_USED(desc, ry);
- REG_MODIFIED(desc, rn);
- AC_USED(desc);
- ALU_FLAGS_MODIFIED(desc);
+ desc.set_reg_used(rx);
+ desc.set_reg_used(ry);
+ desc.set_reg_modified(rn);
+ desc.set_ac_used();
+ desc.set_alu_flags_modified();
break;
case 0x0a: // COMP(Rx, Ry)
case 0x8a: // COMP(Fx, Fy)
- REG_USED(desc, rx);
- REG_USED(desc, ry);
- ALU_FLAGS_MODIFIED(desc);
+ desc.set_reg_used(rx);
+ desc.set_reg_used(ry);
+ desc.set_alu_flags_modified();
break;
case 0x29: // Rn = Rx + 1
@@ -1202,20 +1215,20 @@ bool sharc_frontend::describe_compute(opcode_desc &desc, uint64_t opcode)
case 0xca: // Fn = FLOAT Rx
case 0xc4: // Fn = RECIPS Fx
case 0xc5: // Fn = RSQRTS Fx
- REG_USED(desc, rx);
- REG_MODIFIED(desc, rn);
- ALU_FLAGS_MODIFIED(desc);
+ desc.set_reg_used(rx);
+ desc.set_reg_modified(rn);
+ desc.set_alu_flags_modified();
break;
case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77:
case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f:
{
/* Fixed-point Dual Add/Subtract */
- REG_USED(desc, rx);
- REG_USED(desc, ry);
- REG_MODIFIED(desc, rn);
- REG_MODIFIED(desc, ra);
- ALU_FLAGS_MODIFIED(desc);
+ desc.set_reg_used(rx);
+ desc.set_reg_used(ry);
+ desc.set_reg_modified(rn);
+ desc.set_reg_modified(ra);
+ desc.set_alu_flags_modified();
break;
}
@@ -1223,16 +1236,16 @@ bool sharc_frontend::describe_compute(opcode_desc &desc, uint64_t opcode)
case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff:
{
/* Floating-point Dual Add/Subtract */
- REG_USED(desc, rx);
- REG_USED(desc, ry);
- REG_MODIFIED(desc, rn);
- REG_MODIFIED(desc, ra);
- ALU_FLAGS_MODIFIED(desc);
+ desc.set_reg_used(rx);
+ desc.set_reg_used(ry);
+ desc.set_reg_modified(rn);
+ desc.set_reg_modified(ra);
+ desc.set_alu_flags_modified();
break;
}
default:
- fatalerror("sharc_frontend::describe_compute: unknown ALU op %02X in opcode %04X%08X at %08X", operation, (uint16_t)(opcode >> 32), (uint32_t)(opcode), desc.pc);
+ fatalerror("adsp21062_device::frontend::describe_compute: unknown ALU op %02X in opcode %04X%08X at %08X", operation, (uint16_t)(opcode >> 32), (uint32_t)(opcode), desc.pc);
return false;
}
break;
@@ -1254,10 +1267,10 @@ bool sharc_frontend::describe_compute(opcode_desc &desc, uint64_t opcode)
case 0x70: // Rn = Rx * Ry (SSI)
case 0x78: // Rn = Rx * Ry (SSF)
case 0x79: // Rn = Rx * Ry (SSFR)
- REG_USED(desc, rx);
- REG_USED(desc, ry);
- REG_MODIFIED(desc, rn);
- MULT_FLAGS_MODIFIED(desc);
+ desc.set_reg_used(rx);
+ desc.set_reg_used(ry);
+ desc.set_reg_modified(rn);
+ desc.set_mult_flags_modified();
break;
case 0x44: // MRF = Rx * Ry (UUI)
@@ -1273,9 +1286,9 @@ bool sharc_frontend::describe_compute(opcode_desc &desc, uint64_t opcode)
case 0x7c: // MRF = Rx * Ry (SSF)
case 0x7d: // MRF = Rx * Ry (SSFR)
// TODO: track MRF?
- REG_USED(desc, rx);
- REG_USED(desc, ry);
- MULT_FLAGS_MODIFIED(desc);
+ desc.set_reg_used(rx);
+ desc.set_reg_used(ry);
+ desc.set_mult_flags_modified();
break;
case 0x46: // MRB = Rx * Ry (UUI)
@@ -1291,9 +1304,9 @@ bool sharc_frontend::describe_compute(opcode_desc &desc, uint64_t opcode)
case 0x7e: // MRB = Rx * Ry (SSF)
case 0x7f: // MRB = Rx * Ry (SSFR)
// TODO: track MRB?
- REG_USED(desc, rx);
- REG_USED(desc, ry);
- MULT_FLAGS_MODIFIED(desc);
+ desc.set_reg_used(rx);
+ desc.set_reg_used(ry);
+ desc.set_mult_flags_modified();
break;
case 0x80: // Rn = MRF + Rx * Ry (UUI)
@@ -1309,10 +1322,10 @@ bool sharc_frontend::describe_compute(opcode_desc &desc, uint64_t opcode)
case 0xb8: // Rn = MRF + Rx * Ry (SSF)
case 0xb9: // Rn = MRF + Rx * Ry (SSFR)
// TODO: track MRF?
- REG_USED(desc, rx);
- REG_USED(desc, ry);
- REG_MODIFIED(desc, rn);
- MULT_FLAGS_MODIFIED(desc);
+ desc.set_reg_used(rx);
+ desc.set_reg_used(ry);
+ desc.set_reg_modified(rn);
+ desc.set_mult_flags_modified();
break;
case 0x82: // Rn = MRB + Rx * Ry (UUI)
@@ -1328,10 +1341,10 @@ bool sharc_frontend::describe_compute(opcode_desc &desc, uint64_t opcode)
case 0xba: // Rn = MRB + Rx * Ry (SSF)
case 0xbb: // Rn = MRB + Rx * Ry (SSFR)
// TODO: track MRB?
- REG_USED(desc, rx);
- REG_USED(desc, ry);
- REG_MODIFIED(desc, rn);
- MULT_FLAGS_MODIFIED(desc);
+ desc.set_reg_used(rx);
+ desc.set_reg_used(ry);
+ desc.set_reg_modified(rn);
+ desc.set_mult_flags_modified();
break;
case 0x84: // MRF = MRF + Rx * Ry (UUI)
@@ -1347,9 +1360,9 @@ bool sharc_frontend::describe_compute(opcode_desc &desc, uint64_t opcode)
case 0xbc: // MRF = MRF + Rx * Ry (SSF)
case 0xbd: // MRF = MRF + Rx * Ry (SSFR)
// TODO: track MRF?
- REG_USED(desc, rx);
- REG_USED(desc, ry);
- MULT_FLAGS_MODIFIED(desc);
+ desc.set_reg_used(rx);
+ desc.set_reg_used(ry);
+ desc.set_mult_flags_modified();
break;
case 0x86: // MRB = MRB + Rx * Ry (UUI)
@@ -1366,9 +1379,9 @@ bool sharc_frontend::describe_compute(opcode_desc &desc, uint64_t opcode)
case 0xbf: // MRB = MRB + Rx * Ry (SSFR)
break;
// TODO: track MRB?
- REG_USED(desc, rx);
- REG_USED(desc, ry);
- MULT_FLAGS_MODIFIED(desc);
+ desc.set_reg_used(rx);
+ desc.set_reg_used(ry);
+ desc.set_mult_flags_modified();
break;
case 0xc0: // Rn = MRF - Rx * Ry (UUI)
@@ -1384,10 +1397,10 @@ bool sharc_frontend::describe_compute(opcode_desc &desc, uint64_t opcode)
case 0xf8: // Rn = MRF - Rx * Ry (SSF)
case 0xf9: // Rn = MRF - Rx * Ry (SSFR)
// TODO: track MRF?
- REG_USED(desc, rx);
- REG_USED(desc, ry);
- REG_MODIFIED(desc, rn);
- MULT_FLAGS_MODIFIED(desc);
+ desc.set_reg_used(rx);
+ desc.set_reg_used(ry);
+ desc.set_reg_modified(rn);
+ desc.set_mult_flags_modified();
break;
case 0xc2: // Rn = MRB - Rx * Ry (UUI)
@@ -1403,10 +1416,10 @@ bool sharc_frontend::describe_compute(opcode_desc &desc, uint64_t opcode)
case 0xfa: // Rn = MRB - Rx * Ry (SSF)
case 0xfb: // Rn = MRB - Rx * Ry (SSFR)
// TODO: track MRB?
- REG_USED(desc, rx);
- REG_USED(desc, ry);
- REG_MODIFIED(desc, rn);
- MULT_FLAGS_MODIFIED(desc);
+ desc.set_reg_used(rx);
+ desc.set_reg_used(ry);
+ desc.set_reg_modified(rn);
+ desc.set_mult_flags_modified();
break;
case 0xc4: // MRF = MRF - Rx * Ry (UUI)
@@ -1422,9 +1435,9 @@ bool sharc_frontend::describe_compute(opcode_desc &desc, uint64_t opcode)
case 0xfc: // MRF = MRF - Rx * Ry (SSF)
case 0xfd: // MRF = MRF - Rx * Ry (SSFR)
// TODO: track MRF?
- REG_USED(desc, rx);
- REG_USED(desc, ry);
- MULT_FLAGS_MODIFIED(desc);
+ desc.set_reg_used(rx);
+ desc.set_reg_used(ry);
+ desc.set_mult_flags_modified();
break;
case 0xc6: // MRB = MRB - Rx * Ry (UUI)
@@ -1440,9 +1453,9 @@ bool sharc_frontend::describe_compute(opcode_desc &desc, uint64_t opcode)
case 0xfe: // MRB = MRB - Rx * Ry (SSF)
case 0xff: // MRB = MRB - Rx * Ry (SSFR)
// TODO: track MRB?
- REG_USED(desc, rx);
- REG_USED(desc, ry);
- MULT_FLAGS_MODIFIED(desc);
+ desc.set_reg_used(rx);
+ desc.set_reg_used(ry);
+ desc.set_mult_flags_modified();
break;
case 0x00: // Rn = SAT MRF (UI)
@@ -1450,8 +1463,8 @@ bool sharc_frontend::describe_compute(opcode_desc &desc, uint64_t opcode)
case 0x08: // Rn = SAT MRF (UF)
case 0x09: // Rn = SAT MRF (SF)
// TODO: track MRF?
- REG_MODIFIED(desc, rn);
- MULT_FLAGS_MODIFIED(desc);
+ desc.set_reg_modified(rn);
+ desc.set_mult_flags_modified();
break;
case 0x02: // Rn = SAT MRB (UI)
@@ -1459,8 +1472,8 @@ bool sharc_frontend::describe_compute(opcode_desc &desc, uint64_t opcode)
case 0x0a: // Rn = SAT MRB (UF)
case 0x0b: // Rn = SAT MRB (SF)
// TODO: track MRB?
- REG_MODIFIED(desc, rn);
- MULT_FLAGS_MODIFIED(desc);
+ desc.set_reg_modified(rn);
+ desc.set_mult_flags_modified();
break;
case 0x04: // MRF = SAT MRF (UI)
@@ -1468,7 +1481,7 @@ bool sharc_frontend::describe_compute(opcode_desc &desc, uint64_t opcode)
case 0x0c: // MRF = SAT MRF (UF)
case 0x0d: // MRF = SAT MRF (SF)
// TODO: track MRF?
- MULT_FLAGS_MODIFIED(desc);
+ desc.set_mult_flags_modified();
break;
case 0x06: // MRB = SAT MRB (UI)
@@ -1476,47 +1489,47 @@ bool sharc_frontend::describe_compute(opcode_desc &desc, uint64_t opcode)
case 0x0e: // MRB = SAT MRB (UF)
case 0x0f: // MRB = SAT MRB (SF)
// TODO: track MRB?
- MULT_FLAGS_MODIFIED(desc);
+ desc.set_mult_flags_modified();
break;
case 0x18: // Rn = RND MRF (U)
case 0x19: // Rn = RND MRF (S)
- REG_MODIFIED(desc, rn);
- MULT_FLAGS_MODIFIED(desc);
+ desc.set_reg_modified(rn);
+ desc.set_mult_flags_modified();
break;
case 0x1a: // Rn = RND MRB (U)
case 0x1b: // Rn = RND MRB (S)
- REG_MODIFIED(desc, rn);
- MULT_FLAGS_MODIFIED(desc);
+ desc.set_reg_modified(rn);
+ desc.set_mult_flags_modified();
break;
case 0x1c: // MRF = RND MRF (U)
case 0x1d: // MRF = RND MRF (S)
- MULT_FLAGS_MODIFIED(desc);
+ desc.set_mult_flags_modified();
break;
case 0x1e: // MRB = RND MRB (U)
case 0x1f: // MRB = RND MRB (S)
- MULT_FLAGS_MODIFIED(desc);
+ desc.set_mult_flags_modified();
break;
case 0x14: // MRF = 0
- MULT_FLAGS_MODIFIED(desc);
+ desc.set_mult_flags_modified();
break;
case 0x16: // MRB = 0
- MULT_FLAGS_MODIFIED(desc);
+ desc.set_mult_flags_modified();
break;
case 0x30: // Fn = Fx * Fy
- REG_USED(desc, rx);
- REG_USED(desc, ry);
- REG_MODIFIED(desc, rn);
- MULT_FLAGS_MODIFIED(desc);
+ desc.set_reg_used(rx);
+ desc.set_reg_used(ry);
+ desc.set_reg_modified(rn);
+ desc.set_mult_flags_modified();
break;
default:
- fatalerror("sharc_frontend::describe_compute: unknown mult op %02X in opcode %04X%08X at %08X", operation, (uint16_t)(opcode >> 32), (uint32_t)(opcode), desc.pc);
+ fatalerror("adsp21062_device::frontend::describe_compute: unknown mult op %02X in opcode %04X%08X at %08X", operation, (uint16_t)(opcode >> 32), (uint32_t)(opcode), desc.pc);
}
break;
}
@@ -1534,27 +1547,27 @@ bool sharc_frontend::describe_compute(opcode_desc &desc, uint64_t opcode)
case 0x4c: // Rn = FDEP Rx BY Ry | <bit6>:<len6> (SE)
case 0x40: // Rn = FEXT Rx BY Ry | <bit6>:<len6>
case 0x48: // Rn = FEXT Rx BY Ry | <bit6>:<len6> (SE)
- REG_USED(desc, rx);
- REG_USED(desc, ry);
- REG_MODIFIED(desc, rn);
- SHIFT_FLAGS_MODIFIED(desc);
+ desc.set_reg_used(rx);
+ desc.set_reg_used(ry);
+ desc.set_reg_modified(rn);
+ desc.set_shift_flags_modified();
break;
case 0x20: // Rn = Rn OR LSHIFT Rx BY Ry | <data8>
case 0x24: // Rn = Rn OR ASHIFT Rx BY Ry | <data8>
case 0x64: // Rn = Rn OR FDEP Rx BY Ry | <bit6>:<len6>
case 0x6c: // Rn = Rn OR FDEP Rx BY Ry | <bit6>:<len6> (SE)
- REG_USED(desc, rx);
- REG_USED(desc, ry);
- REG_USED(desc, rn);
- REG_MODIFIED(desc, rn);
- SHIFT_FLAGS_MODIFIED(desc);
+ desc.set_reg_used(rx);
+ desc.set_reg_used(ry);
+ desc.set_reg_used(rn);
+ desc.set_reg_modified(rn);
+ desc.set_shift_flags_modified();
break;
case 0xcc: // BTST Rx BY Ry | <data8>
- REG_USED(desc, rx);
- REG_USED(desc, ry);
- SHIFT_FLAGS_MODIFIED(desc);
+ desc.set_reg_used(rx);
+ desc.set_reg_used(ry);
+ desc.set_shift_flags_modified();
break;
case 0x80: // Rn = EXP Rx
@@ -1563,19 +1576,19 @@ bool sharc_frontend::describe_compute(opcode_desc &desc, uint64_t opcode)
case 0x8c: // Rn = LEFTO Rx
case 0x90: // Rn = FPACK Fx
case 0x94: // Fn = FUNPACK Rx
- REG_USED(desc, rx);
- REG_MODIFIED(desc, rn);
- SHIFT_FLAGS_MODIFIED(desc);
+ desc.set_reg_used(rx);
+ desc.set_reg_modified(rn);
+ desc.set_shift_flags_modified();
break;
default:
- fatalerror("sharc_frontend::describe_compute: unknown shift op %02X in opcode %04X%08X at %08X", operation, (uint16_t)(opcode >> 32), (uint32_t)(opcode), desc.pc);
+ fatalerror("adsp21062_device::frontend::describe_compute: unknown shift op %02X in opcode %04X%08X at %08X", operation, (uint16_t)(opcode >> 32), (uint32_t)(opcode), desc.pc);
}
break;
}
default:
- fatalerror("sharc_frontend::describe_compute: unknown operation type in opcode %04X%08X at %08X", (uint16_t)(opcode >> 32), (uint32_t)(opcode), desc.pc);
+ fatalerror("adsp21062_device::frontend::describe_compute: unknown operation type in opcode %04X%08X at %08X", (uint16_t)(opcode >> 32), (uint32_t)(opcode), desc.pc);
return false;
}
}
@@ -1583,68 +1596,68 @@ bool sharc_frontend::describe_compute(opcode_desc &desc, uint64_t opcode)
return true;
}
-bool sharc_frontend::describe_ureg_access(opcode_desc &desc, int reg, UREG_ACCESS access)
+bool adsp21062_device::frontend::describe_ureg_access(opcode_desc &desc, int reg, UREG_ACCESS access)
{
switch (reg)
{
case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
if (access == UREG_READ)
- REG_USED(desc, reg);
+ desc.set_reg_used(reg);
else
- REG_MODIFIED(desc, reg);
+ desc.set_reg_modified(reg);
break;
case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
if (access == UREG_READ)
- DM_I_USED(desc, reg & 7);
+ desc.set_dm_i_used(reg & 7);
else
- DM_I_MODIFIED(desc, reg & 7);
+ desc.set_dm_i_modified(reg & 7);
break;
case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
if (access == UREG_READ)
- PM_I_USED(desc, reg & 7);
+ desc.set_pm_i_used(reg & 7);
else
- PM_I_MODIFIED(desc, reg & 7);
+ desc.set_pm_i_modified(reg & 7);
break;
case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
if (access == UREG_READ)
- DM_M_USED(desc, reg & 7);
+ desc.set_dm_m_used(reg & 7);
else
- DM_M_MODIFIED(desc, reg & 7);
+ desc.set_dm_m_modified(reg & 7);
break;
case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
if (access == UREG_READ)
- PM_M_USED(desc, reg & 7);
+ desc.set_pm_m_used(reg & 7);
else
- PM_M_MODIFIED(desc, reg & 7);
+ desc.set_pm_m_modified(reg & 7);
break;
case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
if (access == UREG_READ)
- DM_L_USED(desc, reg & 7);
+ desc.set_dm_l_used(reg & 7);
else
- DM_L_MODIFIED(desc, reg & 7);
+ desc.set_dm_l_modified(reg & 7);
break;
case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:
if (access == UREG_READ)
- PM_L_USED(desc, reg & 7);
+ desc.set_pm_l_used(reg & 7);
else
- PM_L_MODIFIED(desc, reg & 7);
+ desc.set_pm_l_modified(reg & 7);
break;
case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
if (access == UREG_READ)
- DM_B_USED(desc, reg & 7);
+ desc.set_dm_b_used(reg & 7);
else
- DM_B_MODIFIED(desc, reg & 7);
+ desc.set_dm_b_modified(reg & 7);
break;
case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f:
if (access == UREG_READ)
- PM_B_USED(desc, reg & 7);
+ desc.set_pm_b_used(reg & 7);
else
- PM_B_MODIFIED(desc, reg & 7);
+ desc.set_pm_b_modified(reg & 7);
break;
case 0x60: // FADDR
@@ -1677,29 +1690,29 @@ bool sharc_frontend::describe_ureg_access(opcode_desc &desc, int reg, UREG_ACCES
case 0x7c: // ASTAT
if (access == UREG_READ)
{
- AZ_USED(desc);
- AN_USED(desc);
- AV_USED(desc);
- AC_USED(desc);
- AS_USED(desc);
- AI_USED(desc);
- MN_USED(desc);
- MV_USED(desc);
- MU_USED(desc);
- MI_USED(desc);
- SV_USED(desc);
- SZ_USED(desc);
- SS_USED(desc);
- BTF_USED(desc);
- AF_USED(desc);
+ desc.set_az_used();
+ desc.set_an_used();
+ desc.set_av_used();
+ desc.set_ac_used();
+ desc.set_as_used();
+ desc.set_ai_used();
+ desc.set_mn_used();
+ desc.set_mv_used();
+ desc.set_mu_used();
+ desc.set_mi_used();
+ desc.set_sv_used();
+ desc.set_sz_used();
+ desc.set_ss_used();
+ desc.set_btf_used();
+ desc.set_af_used();
}
else
{
- ALU_FLAGS_MODIFIED(desc);
- MULT_FLAGS_MODIFIED(desc);
- SHIFT_FLAGS_MODIFIED(desc);
- BTF_MODIFIED(desc);
- AF_MODIFIED(desc);
+ desc.set_alu_flags_modified();
+ desc.set_mult_flags_modified();
+ desc.set_shift_flags_modified();
+ desc.set_btf_modified();
+ desc.set_af_modified();
}
break;
@@ -1717,14 +1730,14 @@ bool sharc_frontend::describe_ureg_access(opcode_desc &desc, int reg, UREG_ACCES
break;
default:
- fatalerror("sharc_frontend::describe_ureg_access: unknown UREG %02X", reg);
+ fatalerror("adsp21062_device::frontend::describe_ureg_access: unknown UREG %02X", reg);
return false;
}
return true;
}
-bool sharc_frontend::describe_shiftop_imm(opcode_desc &desc, int shiftop, int rn, int rx)
+bool adsp21062_device::frontend::describe_shiftop_imm(opcode_desc &desc, int shiftop, int rn, int rx)
{
switch (shiftop)
{
@@ -1738,56 +1751,56 @@ bool sharc_frontend::describe_shiftop_imm(opcode_desc &desc, int shiftop, int rn
case 0x30: // BSET Rx BY <data8>
case 0x31: // BCLR Rx By <data8>
case 0x32: // BTGL Rx BY <data8>
- REG_USED(desc, rx);
- REG_MODIFIED(desc, rn);
- SHIFT_FLAGS_MODIFIED(desc);
+ desc.set_reg_used(rx);
+ desc.set_reg_modified(rn);
+ desc.set_shift_flags_modified();
break;
case 0x08: // Rn = Rn OR LSHIFT Rx BY <data8>
case 0x19: // Rn = Rn OR FDEP Rx BY <bit6>:<len6>
case 0x1b: // Rn = Rn OR FDEP Rx BY <bit6>:<len6> (SE)
- REG_USED(desc, rx);
- REG_USED(desc, rn);
- REG_MODIFIED(desc, rn);
- SHIFT_FLAGS_MODIFIED(desc);
+ desc.set_reg_used(rx);
+ desc.set_reg_used(rn);
+ desc.set_reg_modified(rn);
+ desc.set_shift_flags_modified();
break;
case 0x33: // BTST Rx BY <data8>
- REG_USED(desc, rx);
- SHIFT_FLAGS_MODIFIED(desc);
+ desc.set_reg_used(rx);
+ desc.set_shift_flags_modified();
break;
default:
- fatalerror("sharc_frontend::describe_shiftop_imm: unknown op %02X at %08X", shiftop, desc.pc);
+ fatalerror("adsp21062_device::frontend::describe_shiftop_imm: unknown op %02X at %08X", shiftop, desc.pc);
return false;
}
return true;
}
-void sharc_frontend::describe_if_condition(opcode_desc &desc, int condition)
+void adsp21062_device::frontend::describe_if_condition(opcode_desc &desc, int condition)
{
switch (condition)
{
- case 0x00: AZ_USED(desc); break; /* EQ */
- case 0x01: AZ_USED(desc); AN_USED(desc); break; /* LT */
- case 0x02: AZ_USED(desc); AN_USED(desc); break; /* LE */
- case 0x03: AC_USED(desc); break; /* AC */
- case 0x04: AV_USED(desc); break; /* AV */
- case 0x05: MV_USED(desc); break; /* MV */
- case 0x06: MN_USED(desc); break; /* MS */
- case 0x07: SV_USED(desc); break; /* SV */
- case 0x08: SZ_USED(desc); break; /* SZ */
- case 0x0d: BTF_USED(desc); break; /* TF */
- case 0x10: AZ_USED(desc); break; /* NOT EQUAL */
- case 0x11: AZ_USED(desc); AN_USED(desc); break; /* GE */
- case 0x12: AZ_USED(desc); AN_USED(desc); break; /* GT */
- case 0x13: AC_USED(desc); break; /* NOT AC */
- case 0x14: AV_USED(desc); break; /* NOT AV */
- case 0x15: MV_USED(desc); break; /* NOT MV */
- case 0x16: MN_USED(desc); break; /* NOT MS */
- case 0x17: SV_USED(desc); break; /* NOT SV */
- case 0x18: SZ_USED(desc); break; /* NOT SZ */
- case 0x1d: BTF_USED(desc); break; /* NOT TF */
+ 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 0x03: desc.set_ac_used(); break; // AC
+ case 0x04: desc.set_av_used(); break; // AV
+ case 0x05: desc.set_mv_used(); break; // MV
+ case 0x06: desc.set_mn_used(); break; // MS
+ case 0x07: desc.set_sv_used(); break; // SV
+ 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 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
+ case 0x16: desc.set_mn_used(); break; // NOT MS
+ case 0x17: desc.set_sv_used(); break; // NOT SV
+ case 0x18: desc.set_sz_used(); break; // NOT SZ
+ case 0x1d: desc.set_btf_used(); break; // NOT TF
}
}
diff --git a/src/devices/cpu/sharc/sharcfe.h b/src/devices/cpu/sharc/sharcfe.h
index 1d52b216664..01be597b2a5 100644
--- a/src/devices/cpu/sharc/sharcfe.h
+++ b/src/devices/cpu/sharc/sharcfe.h
@@ -12,15 +12,225 @@
#pragma once
#include "sharc.h"
+
#include "cpu/drcfe.h"
+#include <cassert>
+#include <bitset>
+
-class sharc_frontend : public drc_frontend
+class adsp21062_device::opcode_desc : public opcode_desc_base<opcode_desc, 96>
{
public:
- sharc_frontend(adsp21062_device *sharc, uint32_t window_start, uint32_t window_end, uint32_t max_sequence);
+ enum
+ {
+ LOOP = 0,
+ ASTAT_DELAY_COPY_AZ,
+ ASTAT_DELAY_COPY_AN,
+ ASTAT_DELAY_COPY_AC,
+ ASTAT_DELAY_COPY_AV,
+ ASTAT_DELAY_COPY_MV,
+ ASTAT_DELAY_COPY_MN,
+ ASTAT_DELAY_COPY_SV,
+ ASTAT_DELAY_COPY_SZ,
+ ASTAT_DELAY_COPY_BTF,
+ CALL,
+
+ READS_MEMORY,
+ WRITES_MEMORY,
+
+ EXTRA_FLAG_COUNT
+ };
+
+ using extra_flags = std::bitset<EXTRA_FLAG_COUNT>;
+
+ uint64_t opptr; // copy of opcode
+
+ void set_reg_used(unsigned x) { regin.set(REG_R0 + x); }
+ void set_reg_modified(unsigned x) { regout.set(REG_R0 + x); }
+
+ void set_az_used() { regin.set(REG_AZ); }
+ void set_az_modified() { regout.set(REG_AZ); }
+ void set_av_used() { regin.set(REG_AV); }
+ void set_av_modified() { regout.set(REG_AV); }
+ void set_an_used() { regin.set(REG_AN); }
+ void set_an_modified() { regout.set(REG_AN); }
+ void set_ac_used() { regin.set(REG_AC); }
+ void set_ac_modified() { regout.set(REG_AC); }
+ void set_as_used() { regin.set(REG_AS); }
+ void set_as_modified() { regout.set(REG_AS); }
+ void set_ai_used() { regin.set(REG_AI); }
+ void set_ai_modified() { regout.set(REG_AI); }
+ void set_mn_used() { regin.set(REG_MN); }
+ void set_mn_modified() { regout.set(REG_MN); }
+ void set_mv_used() { regin.set(REG_MV); }
+ void set_mv_modified() { regout.set(REG_MV); }
+ void set_mu_used() { regin.set(REG_MU); }
+ 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_sv_used() { regin.set(REG_SV); }
+ void set_sv_modified() { regout.set(REG_SV); }
+ void set_sz_used() { regin.set(REG_SZ); }
+ void set_sz_modified() { regout.set(REG_SZ); }
+ void set_ss_used() { regin.set(REG_SS); }
+ 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_alu_flags_modified()
+ {
+ set_az_modified();
+ set_an_modified();
+ set_av_modified();
+ set_ac_modified();
+ set_as_modified();
+ set_ai_modified();
+ }
+
+ void set_mult_flags_modified()
+ {
+ set_mn_modified();
+ set_mv_modified();
+ set_mu_modified();
+ set_mi_modified();
+ }
+
+ void set_shift_flags_modified()
+ {
+ set_sz_modified();
+ set_sv_modified();
+ set_ss_modified();
+ }
+
+ bool az_calc_required() const { return regreq[REG_AZ] || in_delay_slot(); }
+ bool av_calc_required() const { return regreq[REG_AV] || in_delay_slot(); }
+ bool an_calc_required() const { return regreq[REG_AN] || in_delay_slot(); }
+ bool ac_calc_required() const { return regreq[REG_AC] || in_delay_slot(); }
+ bool as_calc_required() const { return regreq[REG_AS] || in_delay_slot(); }
+ bool ai_calc_required() const { return regreq[REG_AI] || in_delay_slot(); }
+ bool mn_calc_required() const { return regreq[REG_MN] || in_delay_slot(); }
+ 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 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); }
+ void set_astat_delay_copy_an() { m_extra_flags.set(ASTAT_DELAY_COPY_AN); }
+ void set_astat_delay_copy_ac() { m_extra_flags.set(ASTAT_DELAY_COPY_AC); }
+ void set_astat_delay_copy_av() { m_extra_flags.set(ASTAT_DELAY_COPY_AV); }
+ void set_astat_delay_copy_mv() { m_extra_flags.set(ASTAT_DELAY_COPY_MV); }
+ void set_astat_delay_copy_mn() { m_extra_flags.set(ASTAT_DELAY_COPY_MN); }
+ void set_astat_delay_copy_sv() { m_extra_flags.set(ASTAT_DELAY_COPY_SV); }
+ void set_astat_delay_copy_sz() { m_extra_flags.set(ASTAT_DELAY_COPY_SZ); }
+ void set_astat_delay_copy_btf() { m_extra_flags.set(ASTAT_DELAY_COPY_BTF); }
+ void set_call() { m_extra_flags.set(CALL); }
+ void set_reads_memory() { m_extra_flags.set(READS_MEMORY); }
+ void set_writes_memory() { m_extra_flags.set(WRITES_MEMORY); }
+
+ void set_extra_flags(extra_flags const &flags)
+ {
+ m_extra_flags |= flags;
+ }
+
+ bool loop() const { return m_extra_flags[LOOP]; }
+ bool astat_delay_copy_az() const { return m_extra_flags[ASTAT_DELAY_COPY_AZ]; }
+ bool astat_delay_copy_an() const { return m_extra_flags[ASTAT_DELAY_COPY_AN]; }
+ bool astat_delay_copy_ac() const { return m_extra_flags[ASTAT_DELAY_COPY_AC]; }
+ bool astat_delay_copy_av() const { return m_extra_flags[ASTAT_DELAY_COPY_AV]; }
+ bool astat_delay_copy_mv() const { return m_extra_flags[ASTAT_DELAY_COPY_MV]; }
+ bool astat_delay_copy_mn() const { return m_extra_flags[ASTAT_DELAY_COPY_MN]; }
+ bool astat_delay_copy_sv() const { return m_extra_flags[ASTAT_DELAY_COPY_SV]; }
+ bool astat_delay_copy_sz() const { return m_extra_flags[ASTAT_DELAY_COPY_SZ]; }
+ bool astat_delay_copy_btf() const { return m_extra_flags[ASTAT_DELAY_COPY_BTF]; }
+ bool call() const { return m_extra_flags[CALL]; }
+ bool reads_memory() const { return m_extra_flags[READS_MEMORY]; }
+ bool writes_memory() const { return m_extra_flags[WRITES_MEMORY]; }
+
+ void reset(offs_t curpc, bool in_delay_slot)
+ {
+ static_assert(REG_COUNT <= 96);
+
+ opcode_desc_base::reset(curpc, in_delay_slot);
+
+ opptr = 0;
+ m_extra_flags.reset();
+ }
+
+private:
+ enum
+ {
+ REG_R0 = 0,
+
+ REG_AZ = REG_R0 + 16,
+ REG_AV,
+ REG_AN,
+ REG_AC,
+ REG_AS,
+ REG_AI,
+ REG_MN,
+ REG_MV,
+ REG_MU,
+ REG_MI,
+ 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_M0 = REG_DM_I0 + 8,
+ REG_DM_B0 = REG_DM_M0 + 8,
+ REG_DM_L0 = REG_DM_B0 + 8,
+
+ REG_COUNT = REG_DM_L0 + 8
+ };
+
+ extra_flags m_extra_flags;
+};
+
+
+class adsp21062_device::frontend : public drc_frontend_base<opcode_desc>
+{
+public:
+ frontend(adsp21062_device *sharc, uint32_t window_start, uint32_t window_end, uint32_t max_sequence);
+ ~frontend();
+
+ opcode_desc const *describe_code(offs_t startpc);
+
void flush();
+private:
enum UREG_ACCESS
{
UREG_READ,
@@ -43,7 +253,7 @@ public:
struct LOOP_ENTRY
{
uint16_t entrytype;
- uint32_t userflags;
+ opcode_desc::extra_flags userflags;
};
struct LOOP_DESCRIPTOR
@@ -55,18 +265,15 @@ public:
int condition;
};
-protected:
- // required overrides
- virtual bool describe(opcode_desc &desc, const opcode_desc *prev) override;
+ bool describe(opcode_desc &desc, const opcode_desc *prev);
-private:
bool describe_compute(opcode_desc &desc, uint64_t opcode);
bool describe_ureg_access(opcode_desc &desc, int reg, UREG_ACCESS access);
bool describe_shiftop_imm(opcode_desc &desc, int shiftop, int rn, int rx);
void describe_if_condition(opcode_desc &desc, int condition);
void insert_loop(const LOOP_DESCRIPTOR &loopdesc);
- void add_loop_entry(uint32_t pc, uint8_t type, uint32_t userflags);
+ void add_loop_entry(uint32_t pc, uint8_t type, opcode_desc::extra_flags const &userflags);
bool is_loop_evaluation(uint32_t pc);
bool is_loop_start(uint32_t pc);
bool is_astat_delay_check(uint32_t pc);
diff --git a/src/devices/cpu/sharc/sharcinternal.ipp b/src/devices/cpu/sharc/sharcinternal.ipp
index 8b57f0403a3..e4ad191122a 100644
--- a/src/devices/cpu/sharc/sharcinternal.ipp
+++ b/src/devices/cpu/sharc/sharcinternal.ipp
@@ -8,21 +8,6 @@
#include <algorithm>
-// DRC instruction description flags
-constexpr uint32_t OP_USERFLAG_LOOP = 0x00000001;
-constexpr uint32_t OP_USERFLAG_ASTAT_DELAY_COPY_AZ = 0x00001000;
-constexpr uint32_t OP_USERFLAG_ASTAT_DELAY_COPY_AN = 0x00002000;
-constexpr uint32_t OP_USERFLAG_ASTAT_DELAY_COPY_AC = 0x00004000;
-constexpr uint32_t OP_USERFLAG_ASTAT_DELAY_COPY_AV = 0x00008000;
-constexpr uint32_t OP_USERFLAG_ASTAT_DELAY_COPY_MV = 0x00010000;
-constexpr uint32_t OP_USERFLAG_ASTAT_DELAY_COPY_MN = 0x00020000;
-constexpr uint32_t OP_USERFLAG_ASTAT_DELAY_COPY_SV = 0x00040000;
-constexpr uint32_t OP_USERFLAG_ASTAT_DELAY_COPY_SZ = 0x00080000;
-constexpr uint32_t OP_USERFLAG_ASTAT_DELAY_COPY_BTF = 0x00100000;
-constexpr uint32_t OP_USERFLAG_ASTAT_DELAY_COPY = 0x001ff000;
-constexpr uint32_t OP_USERFLAG_CALL = 0x10000000;
-
-
// constants for IEEE754 single-precision float format
constexpr uint32_t FLOAT_INFINITY = 0x7f800000;
constexpr uint32_t FLOAT_SIGN_MASK = 0x80000000;
diff --git a/src/devices/cpu/unsp/unsp.cpp b/src/devices/cpu/unsp/unsp.cpp
index 5f580c8ce28..657d5f0671e 100644
--- a/src/devices/cpu/unsp/unsp.cpp
+++ b/src/devices/cpu/unsp/unsp.cpp
@@ -26,6 +26,12 @@
#include <climits>
+
+#define SINGLE_INSTRUCTION_MODE (0)
+
+#define ENABLE_UNSP_DRC (0)
+
+
DEFINE_DEVICE_TYPE(UNSP, unsp_device, "unsp", "SunPlus u'nSP (ISA 1.0)")
// 1.1 is just 1.0 with better CPI?
DEFINE_DEVICE_TYPE(UNSP_11, unsp_11_device, "unsp_11", "SunPlus u'nSP (ISA 1.1)")
@@ -248,7 +254,7 @@ void unsp_device::device_start()
m_drcuml->symbol_add(&m_core->m_icount, sizeof(m_core->m_icount), "icount");
/* initialize the front-end helper */
- m_drcfe = std::make_unique<unsp_frontend>(this, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, SINGLE_INSTRUCTION_MODE ? 1 : COMPILE_MAX_SEQUENCE);
+ m_drcfe = std::make_unique<frontend>(this, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, SINGLE_INSTRUCTION_MODE ? 1 : COMPILE_MAX_SEQUENCE);
/* mark the cache dirty so it is updated on next execute */
m_cache_dirty = true;
diff --git a/src/devices/cpu/unsp/unsp.h b/src/devices/cpu/unsp/unsp.h
index 05d8871cb76..0372a491ffb 100644
--- a/src/devices/cpu/unsp/unsp.h
+++ b/src/devices/cpu/unsp/unsp.h
@@ -17,23 +17,15 @@
#pragma once
-#include "cpu/drcfe.h"
-#include "cpu/drcuml.h"
-#include "cpu/drcumlsh.h"
#include "unspdefs.h"
+#include "cpu/drcuml.h"
+
+
/***************************************************************************
CONSTANTS
***************************************************************************/
-/* map variables */
-#define MAPVAR_PC M0
-#define MAPVAR_CYCLES M1
-
-#define SINGLE_INSTRUCTION_MODE (0)
-
-#define ENABLE_UNSP_DRC (0)
-
#define UNSP_LOG_OPCODES (0)
#define UNSP_LOG_REGS (0)
@@ -41,8 +33,6 @@
// TYPE DEFINITIONS
//**************************************************************************
-class unsp_frontend;
-
// ======================> unsp_device
enum
@@ -177,6 +167,10 @@ protected:
int m_icount;
};
+ class frontend;
+ class opcode_desc;
+
+
unsp_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor internal);
// device_t implementation
@@ -300,7 +294,7 @@ private:
drc_cache m_drccache;
std::unique_ptr<drcuml_state> m_drcuml;
- std::unique_ptr<unsp_frontend> m_drcfe;
+ std::unique_ptr<frontend> m_drcfe;
uint32_t m_drcoptions;
uint8_t m_cache_dirty;
diff --git a/src/devices/cpu/unsp/unspdrc.cpp b/src/devices/cpu/unsp/unspdrc.cpp
index a8162b82b22..e041d1020d5 100644
--- a/src/devices/cpu/unsp/unspdrc.cpp
+++ b/src/devices/cpu/unsp/unspdrc.cpp
@@ -4,8 +4,20 @@
#include "emu.h"
#include "unsp.h"
-#include "unspfe.h"
+
#include "unspdefs.h"
+#include "unspfe.h"
+
+#include "cpu/drcumlsh.h"
+
+
+/***************************************************************************
+ CONSTANTS
+***************************************************************************/
+
+/* map variables */
+#define MAPVAR_PC M0
+
void unsp_device::invalidate_cache()
{
@@ -179,7 +191,7 @@ void unsp_device::code_compile_block(offs_t pc)
/* determine the last instruction in this sequence */
for (seqlast = seqhead; seqlast != nullptr; seqlast = seqlast->next())
- if (seqlast->flags & OPFLAG_END_SEQUENCE)
+ if (seqlast->end_sequence())
break;
assert(seqlast != nullptr);
@@ -204,11 +216,11 @@ void unsp_device::code_compile_block(offs_t pc)
}
/* validate this code block if we're not pointing into ROM */
- if (m_program.space().get_write_ptr(seqhead->physpc) != nullptr)
+ if (m_program.space().get_write_ptr(seqhead->pc) != nullptr)
generate_checksum_block(block, compiler, seqhead, seqlast);
/* label this instruction, if it may be jumped to locally */
- if (seqhead->flags & OPFLAG_IS_BRANCH_TARGET)
+ if (seqhead->is_branch_target())
UML_LABEL(block, seqhead->pc | 0x80000000);
/* iterate over instructions in the sequence and compile them */
@@ -525,9 +537,9 @@ void unsp_device::generate_checksum_block(drcuml_block &block, compiler_state &c
}
/* full verification; sum up everything */
- void *memptr = m_program.space().get_write_ptr(seqhead->physpc);
+ void *memptr = m_program.space().get_write_ptr(seqhead->pc);
UML_LOAD(block, I0, memptr, 0, SIZE_WORD, SCALE_x2);
- uint32_t sum = seqhead->opptr.w[0];
+ uint32_t sum = seqhead->opptr[0];
for (int i = 1; i < seqhead->length; i++)
{
UML_LOAD(block, I1, memptr, i, SIZE_WORD, SCALE_x2);
@@ -536,12 +548,12 @@ void unsp_device::generate_checksum_block(drcuml_block &block, compiler_state &c
}
for (curdesc = seqhead->next(); curdesc != seqlast->next(); curdesc = curdesc->next())
{
- if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP))
+ if (!curdesc->virtual_noop())
{
- memptr = m_program.space().get_write_ptr(curdesc->physpc);
+ memptr = m_program.space().get_write_ptr(curdesc->pc);
UML_LOAD(block, I1, memptr, 0, SIZE_WORD, SCALE_x2);
UML_ADD(block, I0, I0, I1);
- sum += curdesc->opptr.w[0];
+ sum += curdesc->opptr[0];
for (int i = 1; i < curdesc->length; i++)
{
UML_LOAD(block, I1, memptr, i, SIZE_WORD, SCALE_x2);
@@ -603,8 +615,8 @@ void unsp_device::generate_branch(drcuml_block &block, compiler_state &compiler,
void unsp_device::generate_sequence_instruction(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc)
{
/* add an entry for the log */
- if (m_drcuml->logging() && !(desc->flags & OPFLAG_VIRTUAL_NOOP))
- log_add_disasm_comment(block, desc->pc, desc->opptr.w[0]);
+ if (m_drcuml->logging() && !desc->virtual_noop())
+ log_add_disasm_comment(block, desc->pc, desc->opptr[0]);
/* set the PC map variable */
UML_MAPVAR(block, MAPVAR_PC, desc->pc);
@@ -620,14 +632,14 @@ void unsp_device::generate_sequence_instruction(drcuml_block &block, compiler_st
UML_CALLC(block, cfunc_log_regs, this);
#endif
- if (!(desc->flags & OPFLAG_VIRTUAL_NOOP))
+ if (!desc->virtual_noop())
{
/* compile the instruction */
if (!generate_opcode(block, compiler, desc))
{
UML_ROLINS(block, mem(&m_core->m_r[REG_SR]), desc->pc, 16, 0x3f);
UML_AND(block, mem(&m_core->m_r[REG_PC]), desc->pc, 0x0000ffff);
- UML_MOV(block, mem(&m_core->m_arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_core->m_arg0), desc->opptr[0]);
UML_CALLC(block, cfunc_unimplemented, this);
}
}
@@ -700,7 +712,7 @@ void unsp_device::generate_update_nz(drcuml_block &block)
bool unsp_device::generate_opcode(drcuml_block &block, compiler_state &compiler, const opcode_desc *desc)
{
- uint32_t op = (uint32_t)desc->opptr.w[0];
+ const uint32_t op = uint32_t(desc->opptr[0]);
generate_add_lpc(block, 1);
@@ -1032,7 +1044,7 @@ bool unsp_device::generate_opcode(drcuml_block &block, compiler_state &compiler,
return false;
// MULS
- UML_MOV(block, mem(&m_core->m_arg0), desc->opptr.w[0]);
+ UML_MOV(block, mem(&m_core->m_arg0), desc->opptr[0]);
UML_CALLC(block, ccfunc_muls, this);
return true;
diff --git a/src/devices/cpu/unsp/unspfe.cpp b/src/devices/cpu/unsp/unspfe.cpp
index f93423379a1..43bd4952ef4 100644
--- a/src/devices/cpu/unsp/unspfe.cpp
+++ b/src/devices/cpu/unsp/unspfe.cpp
@@ -10,21 +10,36 @@
#include "emu.h"
#include "unspfe.h"
+
#include "unspdefs.h"
+#include "cpu/drcfe.ipp"
+
+
/***************************************************************************
INSTRUCTION PARSERS
***************************************************************************/
-unsp_frontend::unsp_frontend(unsp_device *unsp, uint32_t window_start, uint32_t window_end, uint32_t max_sequence)
- : drc_frontend(*unsp, window_start, window_end, max_sequence)
+unsp_device::frontend::frontend(unsp_device *unsp, uint32_t window_start, uint32_t window_end, uint32_t max_sequence)
+ : drc_frontend_base(unsp->space_config(AS_PROGRAM)->page_shift(), window_start, window_end, max_sequence)
, m_cpu(unsp)
{
}
-inline uint16_t unsp_frontend::read_op_word(opcode_desc &desc, int offset)
+unsp_device::frontend::~frontend()
+{
+}
+
+unsp_device::opcode_desc const *unsp_device::frontend::describe_code(offs_t startpc)
{
- return m_cpu->m_cache.read_word(desc.physpc + offset);
+ return do_describe_code(
+ [this] (opcode_desc &desc, opcode_desc const *prev) { return describe(desc, prev); },
+ startpc);
+}
+
+inline uint16_t unsp_device::frontend::read_op_word(opcode_desc &desc, int offset)
+{
+ return m_cpu->m_cache.read_word(desc.pc + offset);
}
/*-------------------------------------------------
@@ -32,9 +47,9 @@ inline uint16_t unsp_frontend::read_op_word(opcode_desc &desc, int offset)
instruction
-------------------------------------------------*/
-bool unsp_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
+bool unsp_device::frontend::describe(opcode_desc &desc, const opcode_desc *prev)
{
- uint16_t op = desc.opptr.w[0] = read_op_word(desc, 0);
+ const uint16_t op = desc.opptr[0] = read_op_word(desc, 0);
/* most instructions are 1 word */
desc.length = 1;
@@ -69,17 +84,19 @@ bool unsp_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
case 11: // JG
case 12: // JVC
case 13: // JVS
- desc.regin[0] |= 1 << unsp_device::REG_SR;
- desc.regout[0] |= 1 << unsp_device::REG_SR;
- desc.regout[0] |= 1 << unsp_device::REG_PC;
+ desc.regin.set(unsp_device::REG_SR);
+ desc.regout.set(unsp_device::REG_SR);
+ desc.regout.set(unsp_device::REG_PC);
desc.targetpc = BRANCH_TARGET_DYNAMIC;
- desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.set_is_conditional_branch();
+ desc.set_end_sequence();
return true;
case 14: // JMP
- desc.regout[0] |= 1 << unsp_device::REG_SR;
- desc.regout[0] |= 1 << unsp_device::REG_PC;
+ desc.regout.set(unsp_device::REG_SR);
+ desc.regout.set(unsp_device::REG_PC);
desc.targetpc = desc.pc + 1 + ((op1 == 0) ? opimm : (0 - opimm));
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
return true;
default:
return false;
@@ -90,12 +107,12 @@ bool unsp_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
uint16_t r0 = opn;
uint16_t r1 = opa;
desc.cycles = 4 + 2 * r0;
- desc.regin[0] |= 1 << opb;
- desc.regout[0] |= 1 << opb;
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.regin.set(opb);
+ desc.regout.set(opb);
+ desc.set_writes_memory();
while (r0--)
{
- desc.regin[0] |= 1 << r1;
+ desc.regin.set(r1);
r1--;
}
return true;
@@ -105,12 +122,14 @@ bool unsp_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
if (op == 0x9a98) // reti
{
desc.cycles = 8;
- desc.regin[0] |= 1 << unsp_device::REG_SP;
- desc.regout[0] |= 1 << unsp_device::REG_SP;
- desc.regout[0] |= 1 << unsp_device::REG_SR;
- desc.regout[0] |= 1 << unsp_device::REG_PC;
+ desc.regin.set(unsp_device::REG_SP);
+ desc.regout.set(unsp_device::REG_SP);
+ desc.regout.set(unsp_device::REG_SR);
+ desc.regout.set(unsp_device::REG_PC);
desc.targetpc = BRANCH_TARGET_DYNAMIC;
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE | OPFLAG_READS_MEMORY;
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
+ desc.set_reads_memory();
return true;
}
else
@@ -118,16 +137,18 @@ bool unsp_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
uint16_t r0 = opn;
uint16_t r1 = opa;
desc.cycles = 4 + 2 * r0;
- desc.regin[0] |= 1 << opb;
- desc.regout[0] |= 1 << opb;
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.regin.set(opb);
+ desc.regout.set(opb);
+ desc.set_reads_memory();
while (r0--)
{
r1++;
- desc.regout[0] |= 1 << r1;
- if (r1 == unsp_device::REG_PC) {
- desc.flags |= OPFLAG_END_SEQUENCE | OPFLAG_IS_UNCONDITIONAL_BRANCH;
+ desc.regout.set(r1);
+ if (r1 == unsp_device::REG_PC)
+ {
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
}
}
return true;
@@ -142,10 +163,10 @@ bool unsp_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
if(opn == 1 && opa != 7)
{
desc.cycles = 12;
- desc.regin[0] |= 1 << opa;
- desc.regin[0] |= 1 << opb;
- desc.regout[0] |= 1 << unsp_device::REG_R3;
- desc.regout[0] |= 1 << unsp_device::REG_R4;
+ desc.regin.set(opa);
+ desc.regin.set(opb);
+ desc.regout.set(unsp_device::REG_R3);
+ desc.regout.set(unsp_device::REG_R4);
return true;
}
return false;
@@ -156,12 +177,15 @@ bool unsp_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
desc.cycles = 9;
desc.length = 2;
desc.targetpc = read_op_word(desc, 1) | ((op & 0x3f) << 16);
- desc.flags = OPFLAG_READS_MEMORY | OPFLAG_WRITES_MEMORY | OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
- desc.regin[0] |= 1 << unsp_device::REG_PC;
- desc.regin[0] |= 1 << unsp_device::REG_SP;
- desc.regout[0] |= 1 << unsp_device::REG_SP;
- desc.regout[0] |= 1 << unsp_device::REG_SR;
- desc.regout[0] |= 1 << unsp_device::REG_PC;
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
+ desc.set_reads_memory();
+ desc.set_writes_memory();
+ desc.regin.set(unsp_device::REG_PC);
+ desc.regin.set(unsp_device::REG_SP);
+ desc.regout.set(unsp_device::REG_SP);
+ desc.regout.set(unsp_device::REG_SR);
+ desc.regout.set(unsp_device::REG_PC);
return true;
}
return false;
@@ -172,10 +196,12 @@ bool unsp_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
desc.cycles = 5;
desc.length = 2;
desc.targetpc = read_op_word(desc, 1) | ((op & 0x3f) << 16);
- desc.flags = OPFLAG_READS_MEMORY | OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
- desc.regin[0] |= 1 << unsp_device::REG_PC;
- desc.regout[0] |= 1 << unsp_device::REG_SR;
- desc.regout[0] |= 1 << unsp_device::REG_PC;
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
+ desc.set_reads_memory();
+ desc.regin.set(unsp_device::REG_PC);
+ desc.regout.set(unsp_device::REG_SR);
+ desc.regout.set(unsp_device::REG_PC);
return true;
}
return false;
@@ -201,13 +227,14 @@ bool unsp_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
case 0x06:
case 0x07: // MULS
- desc.regin[0] |= 1 << opa;
- desc.regin[0] |= 1 << opb;
- desc.regout[0] |= 1 << opa;
- desc.regout[0] |= 1 << opb;
- desc.regout[0] |= 1 << unsp_device::REG_R3;
- desc.regout[0] |= 1 << unsp_device::REG_R4;
- desc.flags = OPFLAG_READS_MEMORY | OPFLAG_WRITES_MEMORY;
+ desc.regin.set(opa);
+ desc.regin.set(opb);
+ desc.regout.set(opa);
+ desc.regout.set(opb);
+ desc.regout.set(unsp_device::REG_R3);
+ desc.regout.set(unsp_device::REG_R4);
+ desc.set_reads_memory();
+ desc.set_writes_memory();
return true;
default:
@@ -217,15 +244,15 @@ bool unsp_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
// At this point, we should be dealing solely with ALU ops.
- desc.regin[0] |= 1 << opa;
+ desc.regin.set(opa);
switch (op1)
{
case 0x00: // r, [bp+imm6]
desc.cycles = 6;
- desc.regin[0] |= 1 << unsp_device::REG_BP;
+ desc.regin.set(unsp_device::REG_BP);
if (op0 != 0x0d)
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_reads_memory();
break;
case 0x01: // r, imm6
@@ -241,21 +268,21 @@ bool unsp_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
switch (lsbits)
{
case 0: // r, [r]
- desc.regin[0] |= 1 << unsp_device::REG_SR;
- desc.regin[0] |= 1 << opb;
+ desc.regin.set(unsp_device::REG_SR);
+ desc.regin.set(opb);
if (op0 != 0x0d)
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_reads_memory();
break;
case 1: // r, [<ds:>r--]
case 2: // r, [<ds:>r++]
case 3: // r, [<ds:>++r]
- desc.regin[0] |= 1 << unsp_device::REG_SR;
- desc.regin[0] |= 1 << opb;
- desc.regout[0] |= 1 << unsp_device::REG_SR;
- desc.regout[0] |= 1 << opb;
+ desc.regin.set(unsp_device::REG_SR);
+ desc.regin.set(opb);
+ desc.regout.set(unsp_device::REG_SR);
+ desc.regout.set(opb);
if (op0 != 0x0d)
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_reads_memory();
break;
}
}
@@ -264,17 +291,17 @@ bool unsp_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
switch (lsbits)
{
case 0: // r, [r]
- desc.regin[0] |= 1 << opb;
+ desc.regin.set(opb);
if (op0 != 0x0d)
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_reads_memory();
break;
case 1: // r, [r--]
case 2: // r, [r++]
case 3: // r, [++r]
- desc.regin[0] |= 1 << opb;
- desc.regout[0] |= 1 << opb;
+ desc.regin.set(opb);
+ desc.regout.set(opb);
if (op0 != 0x0d)
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.set_reads_memory();
break;
}
}
@@ -285,49 +312,49 @@ bool unsp_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
switch (opn)
{
case 0x00: // r
- desc.cycles = (opa == 7 ? 5 : 3);
- desc.regin[0] |= 1 << opb;
+ desc.cycles = (opa == 7) ? 5 : 3;
+ desc.regin.set(opb);
break;
case 0x01: // imm16
- desc.cycles = (opa == 7 ? 5 : 4);
+ desc.cycles = (opa == 7) ? 5 : 4;
desc.length = 2;
- desc.regin[0] |= 1 << opb;
- desc.regin[0] |= 1 << unsp_device::REG_SR;
- desc.regin[0] |= 1 << unsp_device::REG_PC;
- desc.regout[0] |= 1 << unsp_device::REG_SR;
- desc.regout[0] |= 1 << unsp_device::REG_PC;
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.regin.set(opb);
+ desc.regin.set(unsp_device::REG_SR);
+ desc.regin.set(unsp_device::REG_PC);
+ desc.regout.set(unsp_device::REG_SR);
+ desc.regout.set(unsp_device::REG_PC);
+ desc.set_reads_memory();
break;
case 0x02: // [imm16]
case 0x03: // store [imm16], r
- desc.cycles = (opa == 7 ? 8 : 7);
+ desc.cycles = (opa == 7) ? 8 : 7;
desc.length = 2;
- desc.regin[0] |= 1 << opb;
- desc.regin[0] |= 1 << unsp_device::REG_SR;
- desc.regin[0] |= 1 << unsp_device::REG_PC;
- desc.regout[0] |= 1 << unsp_device::REG_SR;
- desc.regout[0] |= 1 << unsp_device::REG_PC;
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.regin.set(opb);
+ desc.regin.set(unsp_device::REG_SR);
+ desc.regin.set(unsp_device::REG_PC);
+ desc.regout.set(unsp_device::REG_SR);
+ desc.regout.set(unsp_device::REG_PC);
+ desc.set_reads_memory();
break;
default: // Shifted ops
- desc.cycles = (opa == 7 ? 5 : 3);
- desc.regin[0] |= 1 << opb;
+ desc.cycles = (opa == 7) ? 5 : 3;
+ desc.regin.set(opb);
break;
}
break;
case 0x05: // More shifted ops
case 0x06: // Rotated ops
- desc.cycles = (opa == 7 ? 5 : 3);
- desc.regin[0] |= 1 << opb;
+ desc.cycles = (opa == 7) ? 5 : 3;
+ desc.regin.set(opb);
break;
case 0x07: // Direct 8
- desc.cycles = (opa == 7 ? 6 : 5);
- desc.flags |= OPFLAG_READS_MEMORY;
+ desc.cycles = (opa == 7) ? 6 : 5;
+ desc.set_reads_memory();
break;
default:
@@ -346,28 +373,29 @@ bool unsp_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
case 0x09: // Load
case 0x0a: // OR
case 0x0b: // AND
- desc.regout[0] |= 1 << unsp_device::REG_SR;
+ desc.regout.set(unsp_device::REG_SR);
break;
case 0x04: // Compare
case 0x0c: // Test
- desc.regout[0] |= 1 << unsp_device::REG_SR;
+ desc.regout.set(unsp_device::REG_SR);
return true;
case 0x0d: // Store
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_writes_memory();
return true;
}
if (op1 == 0x04 && opn == 0x03) // store [imm16], r
{
- desc.flags |= OPFLAG_WRITES_MEMORY;
+ desc.set_writes_memory();
}
else
{
- desc.regout[0] |= 1 << opa;
+ desc.regout.set(opa);
if (opa == 7)
{
desc.targetpc = BRANCH_TARGET_DYNAMIC;
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
+ desc.set_is_unconditional_branch();
+ desc.set_end_sequence();
}
}
diff --git a/src/devices/cpu/unsp/unspfe.h b/src/devices/cpu/unsp/unspfe.h
index c30b2721e0a..60f9c4e6ce8 100644
--- a/src/devices/cpu/unsp/unspfe.h
+++ b/src/devices/cpu/unsp/unspfe.h
@@ -6,22 +6,55 @@
#pragma once
#include "unsp.h"
+
#include "cpu/drcfe.h"
-class unsp_frontend : public drc_frontend
+#include <algorithm>
+
+
+class unsp_device::opcode_desc : public opcode_desc_base<opcode_desc, 16>
+{
+public:
+ uint16_t opptr[2]; // copy of opcode
+
+ uint32_t cycles; // number of cycles needed to execute
+
+ void set_reads_memory() { m_reads_memory = true; }
+ void set_writes_memory() { m_writes_memory = true; }
+
+ bool reads_memory() const { return m_reads_memory; }
+ bool writes_memory() const { return m_writes_memory; }
+
+ void reset(offs_t curpc, bool in_delay_slot)
+ {
+ opcode_desc_base::reset(curpc, in_delay_slot);
+
+ std::fill(std::begin(opptr), std::end(opptr), 0);
+ cycles = 0;
+ m_reads_memory = false;
+ m_writes_memory = false;
+ }
+
+private:
+ bool m_reads_memory;
+ bool m_writes_memory;
+};
+
+
+class unsp_device::frontend : public drc_frontend_base<opcode_desc>
{
public:
- unsp_frontend(unsp_device *unsp, uint32_t window_start, uint32_t window_end, uint32_t max_sequence);
- void flush();
+ frontend(unsp_device *unsp, uint32_t window_start, uint32_t window_end, uint32_t max_sequence);
+ ~frontend();
-protected:
- // required overrides
- virtual bool describe(opcode_desc &desc, const opcode_desc *prev) override;
+ opcode_desc const *describe_code(offs_t startpc);
private:
- inline uint16_t read_op_word(opcode_desc &desc, int offset);
+ bool describe(opcode_desc &desc, const opcode_desc *prev);
+
+ uint16_t read_op_word(opcode_desc &desc, int offset);
unsp_device *m_cpu;
};
-#endif /* MAME_CPU_UNSP_UNSPFE_H */
+#endif // MAME_CPU_UNSP_UNSPFE_H
diff --git a/src/devices/sound/swp30.h b/src/devices/sound/swp30.h
index 671130a9d40..fa03df9e50d 100644
--- a/src/devices/sound/swp30.h
+++ b/src/devices/sound/swp30.h
@@ -8,9 +8,9 @@
#pragma once
-#include "cpu/drcfe.h"
#include "cpu/drcuml.h"
+
class swp30_disassembler : public util::disasm_interface
{
public: