summaryrefslogtreecommitdiffstatshomepage
path: root/src
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 /src
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.
Diffstat (limited to 'src')
-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
55 files changed, 4230 insertions, 3219 deletions
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: