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.h188
1 files changed, 188 insertions, 0 deletions
diff --git a/src/emu/cpu/drcfe.h b/src/emu/cpu/drcfe.h
new file mode 100644
index 00000000000..44661034251
--- /dev/null
+++ b/src/emu/cpu/drcfe.h
@@ -0,0 +1,188 @@
+/***************************************************************************
+
+ drcfe.h
+
+ Generic dynamic recompiler frontend structures and utilities.
+
+ Copyright (c) 2007, Aaron Giles
+ Released for general use under the MAME license
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+****************************************************************************
+
+ Concepts:
+
+ Dynamic recompiling cores are generally broken into a platform-neutral
+ "frontend", which performs some level of analysis on the code, and a
+ platform-specific "backend", which generates the recompiled machine
+ code.
+
+ The frontend's job is generally to walk through the instruction stream,
+ identifying basic blocks, or "sequences" of code that can be compiled
+ and optimized as a unit. This scanning involves recursively walking
+ the instruction stream, following branches, etc., within a specific
+ "code window", relative to the current PC.
+
+ As the frontend walks through the code, it generates a list of opcode
+ "descriptions", one per visited opcode, providing information about
+ code flow, exception handling, and other characteristics. Once the
+ walkthrough is finished, these descriptions are assembled together into
+ a linked list and returned for further processing by the backend.
+
+***************************************************************************/
+
+#ifndef __DRCFE_H__
+#define __DRCFE_H__
+
+#ifdef PTR64
+#include "x64drc.h"
+#else
+#include "x86drc.h"
+#endif
+
+
+
+/***************************************************************************
+ CONSTANTS
+***************************************************************************/
+
+/* this defines a branch targetpc that is dynamic at runtime */
+#define 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 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 */
+
+/* opcode virtual->physical translation flags */
+#define OPFLAG_VALIDATE_TLB 0x00000200 /* instruction must validate TLB before execution */
+#define OPFLAG_MODIFIES_TRANSLATION 0x00000400 /* instruction modifies the TLB */
+#define OPFLAG_COMPILER_PAGE_FAULT 0x00000800 /* compiler hit a page fault when parsing */
+#define OPFLAG_COMPILER_UNMAPPED 0x00001000 /* compiler hit unmapped memory when parsing */
+
+/* opcode flags */
+#define OPFLAG_INVALID_OPCODE 0x00002000 /* instruction is invalid */
+#define OPFLAG_VIRTUAL_NOOP 0x00004000 /* instruction is a virtual no-op */
+
+/* opcode sequence flow flags */
+#define OPFLAG_REDISPATCH 0x00008000 /* instruction must redispatch after completion */
+#define OPFLAG_RETURN_TO_START 0x00010000 /* instruction must jump back to the beginning after completion */
+#define OPFLAG_END_SEQUENCE 0x00020000 /* this is the last instruction in a sequence */
+#define OPFLAG_CAN_CHANGE_MODES 0x00040000 /* instruction can change modes */
+
+/* execution semantics */
+#define OPFLAG_READS_MEMORY 0x00080000 /* instruction reads memory */
+#define OPFLAG_WRITES_MEMORY 0x00100000 /* instruction writes memory */
+#define OPFLAG_VARIABLE_SHIFT 0x00200000 /* instruction performs a variable count shift */
+#define OPFLAG_MULTIPLY_DIVIDE 0x00400000 /* instruction performs a multiply/divide */
+
+
+
+/***************************************************************************
+ TYPE DEFINITIONS
+***************************************************************************/
+
+/* opaque internal state */
+typedef struct _drcfe_state drcfe_state;
+
+
+/* register information as bitmasks */
+typedef struct _drc_reginfo drc_reginfo;
+struct _drc_reginfo
+{
+ UINT64 used; /* bitmask of used registers */
+ UINT64 modified; /* bitmask of modified registers */
+ UINT64 constant; /* bitmask of constant registers */
+ UINT64 liveread; /* bitmask of registers that are live for reading */
+ UINT64 livewrite; /* bitmask of registers that are live for writing */
+};
+
+
+/* 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 * 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 */
+
+ /* pointer to the current opcode */
+ union
+ {
+ void * v;
+ UINT8 * b;
+ UINT16 * w;
+ UINT32 * l;
+ UINT64 * q;
+ } 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 */
+ drc_reginfo gpr; /* register info for GPRs */
+ drc_reginfo fpr; /* register info for FPRs */
+};
+
+
+/* callback function that is used to describe a single opcode */
+typedef int (*drcfe_describe)(void *param, opcode_desc *desc);
+
+
+/* description of a given opcode */
+typedef struct _drcfe_config drcfe_config;
+struct _drcfe_config
+{
+ 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 describe; /* callback to describe a single instruction */
+};
+
+/*
+ for each register:
+ callback to load
+ callback to store
+ pointer to memory
+ if (pointer != NULL)
+ - can return reference to memory for operations
+ else
+ - must always load/store from register
+*/
+
+
+/***************************************************************************
+ FUNCTION PROTOTYPES
+***************************************************************************/
+
+/* initializate the drcfe state */
+drcfe_state *drcfe_init(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