summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/cpu/drcfe.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/cpu/drcfe.h')
-rw-r--r--src/emu/cpu/drcfe.h224
1 files changed, 128 insertions, 96 deletions
diff --git a/src/emu/cpu/drcfe.h b/src/emu/cpu/drcfe.h
index 38de85a6ccf..7849aed73c9 100644
--- a/src/emu/cpu/drcfe.h
+++ b/src/emu/cpu/drcfe.h
@@ -4,9 +4,36 @@
Generic dynamic recompiler frontend structures and utilities.
+****************************************************************************
+
Copyright Aaron Giles
- Released for general non-commercial use under the MAME license
- Visit http://mamedev.org for licensing and usage restrictions.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name 'MAME' nor the names of its contributors may be
+ used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
****************************************************************************
@@ -37,125 +64,130 @@
#define __DRCFE_H__
-/***************************************************************************
- CONSTANTS
-***************************************************************************/
+//**************************************************************************
+// CONSTANTS
+//**************************************************************************
-/* this defines a branch targetpc that is dynamic at runtime */
-#define BRANCH_TARGET_DYNAMIC (~0)
+// this defines a branch targetpc that is dynamic at runtime
+const offs_t BRANCH_TARGET_DYNAMIC = ~0;
-/* opcode branch flags */
-#define OPFLAG_IS_UNCONDITIONAL_BRANCH 0x00000001 /* instruction is unconditional branch */
-#define OPFLAG_IS_CONDITIONAL_BRANCH 0x00000002 /* instruction is conditional branch */
-#define OPFLAG_IS_BRANCH (OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_IS_CONDITIONAL_BRANCH)
-#define OPFLAG_IS_BRANCH_TARGET 0x00000004 /* instruction is the target of a branch */
-#define OPFLAG_IN_DELAY_SLOT 0x00000008 /* instruction is in the delay slot of a branch */
-#define OPFLAG_INTRABLOCK_BRANCH 0x00000010 /* instruction branches within the block */
+// opcode branch flags
+const UINT32 OPFLAG_IS_UNCONDITIONAL_BRANCH = 0x00000001; // instruction is unconditional branch
+const UINT32 OPFLAG_IS_CONDITIONAL_BRANCH = 0x00000002; // instruction is conditional branch
+const UINT32 OPFLAG_IS_BRANCH = (OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_IS_CONDITIONAL_BRANCH);
+const UINT32 OPFLAG_IS_BRANCH_TARGET = 0x00000004; // instruction is the target of a branch
+const UINT32 OPFLAG_IN_DELAY_SLOT = 0x00000008; // instruction is in the delay slot of a branch
+const UINT32 OPFLAG_INTRABLOCK_BRANCH = 0x00000010; // instruction branches within the block
-/* opcode exception flags */
-#define OPFLAG_CAN_TRIGGER_SW_INT 0x00000020 /* instruction can trigger a software interrupt */
-#define OPFLAG_CAN_EXPOSE_EXTERNAL_INT 0x00000040 /* instruction can expose an external interrupt */
-#define OPFLAG_CAN_CAUSE_EXCEPTION 0x00000080 /* instruction may generate exception */
-#define OPFLAG_WILL_CAUSE_EXCEPTION 0x00000100 /* instruction will generate exception */
-#define OPFLAG_PRIVILEGED 0x00000200 /* instruction is privileged */
+// opcode exception flags
+const UINT32 OPFLAG_CAN_TRIGGER_SW_INT = 0x00000020; // instruction can trigger a software interrupt
+const UINT32 OPFLAG_CAN_EXPOSE_EXTERNAL_INT = 0x00000040; // instruction can expose an external interrupt
+const UINT32 OPFLAG_CAN_CAUSE_EXCEPTION = 0x00000080; // instruction may generate exception
+const UINT32 OPFLAG_WILL_CAUSE_EXCEPTION = 0x00000100; // instruction will generate exception
+const UINT32 OPFLAG_PRIVILEGED = 0x00000200; // instruction is privileged
-/* opcode virtual->physical translation flags */
-#define OPFLAG_VALIDATE_TLB 0x00000400 /* instruction must validate TLB before execution */
-#define OPFLAG_MODIFIES_TRANSLATION 0x00000800 /* instruction modifies the TLB */
-#define OPFLAG_COMPILER_PAGE_FAULT 0x00001000 /* compiler hit a page fault when parsing */
-#define OPFLAG_COMPILER_UNMAPPED 0x00002000 /* compiler hit unmapped memory when parsing */
+// opcode virtual->physical translation flags
+const UINT32 OPFLAG_VALIDATE_TLB = 0x00000400; // instruction must validate TLB before execution
+const UINT32 OPFLAG_MODIFIES_TRANSLATION = 0x00000800; // instruction modifies the TLB
+const UINT32 OPFLAG_COMPILER_PAGE_FAULT = 0x00001000; // compiler hit a page fault when parsing
+const UINT32 OPFLAG_COMPILER_UNMAPPED = 0x00002000; // compiler hit unmapped memory when parsing
-/* opcode flags */
-#define OPFLAG_INVALID_OPCODE 0x00004000 /* instruction is invalid */
-#define OPFLAG_VIRTUAL_NOOP 0x00008000 /* instruction is a virtual no-op */
+// opcode flags
+const UINT32 OPFLAG_INVALID_OPCODE = 0x00004000; // instruction is invalid
+const UINT32 OPFLAG_VIRTUAL_NOOP = 0x00008000; // instruction is a virtual no-op
-/* opcode sequence flow flags */
-#define OPFLAG_REDISPATCH 0x00010000 /* instruction must redispatch after completion */
-#define OPFLAG_RETURN_TO_START 0x00020000 /* instruction must jump back to the beginning after completion */
-#define OPFLAG_END_SEQUENCE 0x00040000 /* this is the last instruction in a sequence */
-#define OPFLAG_CAN_CHANGE_MODES 0x00080000 /* instruction can change modes */
+// opcode sequence flow flags
+const UINT32 OPFLAG_REDISPATCH = 0x00010000; // instruction must redispatch after completion
+const UINT32 OPFLAG_RETURN_TO_START = 0x00020000; // instruction must jump back to the beginning after completion
+const UINT32 OPFLAG_END_SEQUENCE = 0x00040000; // this is the last instruction in a sequence
+const UINT32 OPFLAG_CAN_CHANGE_MODES = 0x00080000; // instruction can change modes
-/* execution semantics */
-#define OPFLAG_READS_MEMORY 0x00100000 /* instruction reads memory */
-#define OPFLAG_WRITES_MEMORY 0x00200000 /* instruction writes memory */
+// execution semantics
+const UINT32 OPFLAG_READS_MEMORY = 0x00100000; // instruction reads memory
+const UINT32 OPFLAG_WRITES_MEMORY = 0x00200000; // instruction writes memory
-/***************************************************************************
- TYPE DEFINITIONS
-***************************************************************************/
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
-/* opaque internal state */
-typedef struct _drcfe_state drcfe_state;
+// description of a given opcode
+struct opcode_desc
+{
+ opcode_desc *next() const { return m_next; }
+ // 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
-/* description of a given opcode */
-typedef struct _opcode_desc opcode_desc;
-struct _opcode_desc
-{
- /* links to other descriptions */
- opcode_desc * next; /* pointer to next description */
- opcode_desc * prev; /* pointer to previous description */
- opcode_desc * branch; /* pointer back to branch description for delay slots */
- opcode_desc * 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 */
+ // 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
{
UINT8 b[16];
UINT16 w[8];
UINT32 l[4];
UINT64 q[2];
- } opptr; /* pointer to opcode memory */
-
- /* information about this instruction's execution */
- UINT8 length; /* length in bytes of this opcode */
- UINT8 delayslots; /* number of delay slots (for branches) */
- UINT8 skipslots; /* number of skip slots (for branches) */
- UINT32 flags; /* OPFLAG_* opcode flags */
- UINT32 cycles; /* number of cycles needed to execute */
-
- /* register usage information */
- UINT32 regin[4]; /* input registers */
- UINT32 regout[4]; /* output registers */
- UINT32 regreq[4]; /* required output registers */
+ } opptr; // pointer to opcode memory
+
+ // information about this instruction's execution
+ UINT8 length; // length in bytes of this opcode
+ UINT8 delayslots; // number of delay slots (for branches)
+ UINT8 skipslots; // number of skip slots (for branches)
+ UINT32 flags; // OPFLAG_* opcode flags
+ UINT32 cycles; // number of cycles needed to execute
+
+ // register usage information
+ UINT32 regin[4]; // input registers
+ UINT32 regout[4]; // output registers
+ UINT32 regreq[4]; // required output registers
};
-/* callback function that is used to describe a single opcode */
-typedef int (*drcfe_describe_func)(void *param, opcode_desc *desc, const opcode_desc *prev);
-
-
-/* description of a given opcode */
-typedef struct _drcfe_config drcfe_config;
-struct _drcfe_config
+// DRC frontend state
+class drc_frontend
{
- UINT32 window_start; /* code window start offset = startpc - window_start */
- UINT32 window_end; /* code window end offset = startpc + window_end */
- UINT32 max_sequence; /* maximum instructions to include in a sequence */
- drcfe_describe_func describe; /* callback to describe a single instruction */
+public:
+ // construction/destruction
+ drc_frontend(device_t &cpu, UINT32 window_start, UINT32 window_end, UINT32 max_sequence);
+ virtual ~drc_frontend();
+
+ // describe a block
+ const opcode_desc *describe_code(offs_t startpc);
+
+protected:
+ // required overrides
+ virtual bool describe(opcode_desc &desc, const opcode_desc *prev) = 0;
+
+private:
+ // internal helpers
+ opcode_desc *describe_one(offs_t curpc, const opcode_desc *prevdesc);
+ void build_sequence(int start, int end, UINT32 endflag);
+ void accumulate_required_backwards(opcode_desc &desc, UINT32 *reqmask);
+ void release_descriptions();
+
+ // configuration parameters
+ UINT32 m_window_start; // code window start offset = startpc - window_start
+ UINT32 m_window_end; // code window end offset = startpc + window_end
+ UINT32 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
+
+ // 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
+ opcode_desc ** m_desc_array; // array of descriptions in PC order
};
-
-/***************************************************************************
- FUNCTION PROTOTYPES
-***************************************************************************/
-
-/* initializate the drcfe state */
-drcfe_state *drcfe_init(device_t *cpu, const drcfe_config *config, void *param);
-
-/* clean up after ourselves */
-void drcfe_exit(drcfe_state *drcfe);
-
-/* describe a sequence of code that falls within the configured window relative to the specified startpc */
-const opcode_desc *drcfe_describe_code(drcfe_state *drcfe, offs_t startpc);
-
-
#endif /* __DRCFE_H__ */