summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/cpu/x86drc.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/cpu/x86drc.h')
-rw-r--r--src/emu/cpu/x86drc.h194
1 files changed, 194 insertions, 0 deletions
diff --git a/src/emu/cpu/x86drc.h b/src/emu/cpu/x86drc.h
new file mode 100644
index 00000000000..b3985b720d5
--- /dev/null
+++ b/src/emu/cpu/x86drc.h
@@ -0,0 +1,194 @@
+/***************************************************************************
+
+ x86drc.h
+
+ x86 Dynamic recompiler support routines.
+
+ Copyright (c) 1996-2007, Nicola Salmoria and the MAME Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+***************************************************************************/
+
+#pragma once
+
+#ifndef __X86DRC_H__
+#define __X86DRC_H__
+
+#include "cpuintrf.h"
+#include "x86emit.h"
+
+
+/***************************************************************************
+ TYPE DEFINITIONS
+***************************************************************************/
+
+/* PC and pointer pair */
+typedef struct _pc_ptr_pair pc_ptr_pair;
+struct _pc_ptr_pair
+{
+ UINT32 pc;
+ x86code * target;
+};
+
+
+/* core interface structure for the drc common code */
+typedef struct _drc_core drc_core;
+struct _drc_core
+{
+ UINT8 * cache_base; /* base pointer to the compiler cache */
+ UINT8 * cache_top; /* current top of cache */
+ UINT8 * cache_danger; /* high water mark for the end */
+ UINT8 * cache_end; /* end of cache memory */
+ size_t cache_size; /* cache allocated size */
+ UINT8 cache_allocated; /* did the DRC core allocate the cache? */
+
+ x86code *** lookup_l1; /* level 1 lookup */
+ x86code ** lookup_l2_recompile; /* level 2 lookup populated with recompile pointers */
+ UINT8 l1bits; /* number of bits in level 1 lookup */
+ UINT8 l2bits; /* number of bits in level 2 lookup */
+ UINT8 l1shift; /* shift to go from PC to level 1 lookup */
+ UINT32 l2mask; /* mask to go from PC to level 2 lookup */
+ UINT8 l2scale; /* scale to get from masked PC value to final level 2 lookup */
+
+ void (*entry_point)(void); /* pointer to asm entry point */
+ x86code * out_of_cycles; /* pointer to out of cycles jump point */
+ x86code * recompile; /* pointer to recompile jump point */
+ x86code * dispatch; /* pointer to dispatch jump point */
+ x86code * flush; /* pointer to flush jump point */
+
+ UINT32 * pcptr; /* pointer to where the PC is stored */
+ UINT32 * icountptr; /* pointer to where the icount is stored */
+ UINT32 * esiptr; /* pointer to where the volatile data in ESI is stored */
+ UINT8 pc_in_memory; /* true if the PC is stored in memory */
+ UINT8 icount_in_memory; /* true if the icount is stored in memory */
+
+ UINT8 uses_fp; /* true if we need the FP unit */
+ UINT8 uses_sse; /* true if we need the SSE unit */
+ UINT16 fpcw_curr; /* current FPU control word */
+ UINT32 mxcsr_curr; /* current SSE control word */
+ UINT16 fpcw_save; /* saved FPU control word */
+ UINT32 mxcsr_save; /* saved SSE control word */
+
+ pc_ptr_pair *sequence_list; /* PC/pointer sets for the current instruction sequence */
+ UINT32 sequence_count; /* number of instructions in the current sequence */
+ UINT32 sequence_count_max; /* max number of instructions in the current sequence */
+ pc_ptr_pair *tentative_list; /* PC/pointer sets for tentative branches */
+ UINT32 tentative_count; /* number of tentative branches */
+ UINT32 tentative_count_max; /* max number of tentative branches */
+
+ void (*cb_reset)(struct _drc_core *drc); /* callback when the cache is reset */
+ void (*cb_recompile)(struct _drc_core *drc); /* callback when code needs to be recompiled */
+ void (*cb_entrygen)(struct _drc_core *drc); /* callback before generating the dispatcher on entry */
+};
+
+
+/* configuration structure for the drc common code */
+typedef struct _drc_config drc_config;
+struct _drc_config
+{
+ UINT8 * cache_base; /* base pointer to the compiler cache */
+ UINT32 cache_size; /* size of cache to allocate */
+ UINT32 max_instructions; /* maximum instructions per sequence */
+ UINT8 address_bits; /* number of live address bits in the PC */
+ UINT8 lsbs_to_ignore; /* number of LSBs to ignore on the PC */
+ UINT8 uses_fp; /* true if we need the FP unit */
+ UINT8 uses_sse; /* true if we need the SSE unit */
+ UINT8 pc_in_memory; /* true if the PC is stored in memory */
+ UINT8 icount_in_memory; /* true if the icount is stored in memory */
+
+ UINT32 * pcptr; /* pointer to where the PC is stored */
+ UINT32 * icountptr; /* pointer to where the icount is stored */
+ UINT32 * esiptr; /* pointer to where the volatile data in ESI is stored */
+
+ void (*cb_reset)(drc_core *drc); /* callback when the cache is reset */
+ void (*cb_recompile)(drc_core *drc); /* callback when code needs to be recompiled */
+ void (*cb_entrygen)(drc_core *drc); /* callback before generating the dispatcher on entry */
+};
+
+
+/* structure to hold link data to be filled in later */
+typedef struct _link_info link_info;
+struct _link_info
+{
+ UINT8 size;
+ UINT8 * target;
+};
+
+
+
+/***************************************************************************
+ MACROS
+***************************************************************************/
+
+/* use this macro in emit_* instructions to make them shorter */
+#define DRCTOP &drc->cache_top
+
+
+
+/***************************************************************************
+ HELPER MACROS
+***************************************************************************/
+
+/* useful macros for accessing hi/lo portions of 64-bit values */
+#define LO(x) (&(((UINT32 *)(UINT32)(x))[0]))
+#define HI(x) (&(((UINT32 *)(UINT32)(x))[1]))
+
+
+
+/***************************************************************************
+ CONSTANTS
+***************************************************************************/
+
+/* features */
+#define CPUID_FEATURES_MMX (1 << 23)
+#define CPUID_FEATURES_SSE (1 << 26)
+#define CPUID_FEATURES_SSE2 (1 << 25)
+#define CPUID_FEATURES_CMOV (1 << 15)
+#define CPUID_FEATURES_TSC (1 << 4)
+
+
+
+/***************************************************************************
+ FUNCTION PROTOTYPES
+***************************************************************************/
+
+/* init/shutdown */
+drc_core *drc_init(UINT8 cpunum, drc_config *config);
+void *drc_alloc(drc_core *drc, size_t amount);
+void drc_cache_reset(drc_core *drc);
+void drc_execute(drc_core *drc);
+void drc_exit(drc_core *drc);
+
+/* code management */
+void drc_begin_sequence(drc_core *drc, UINT32 pc);
+void drc_end_sequence(drc_core *drc);
+void drc_register_code_at_cache_top(drc_core *drc, UINT32 pc);
+void *drc_get_code_at_pc(drc_core *drc, UINT32 pc);
+
+/* standard appendages */
+void drc_append_dispatcher(drc_core *drc);
+void drc_append_fixed_dispatcher(drc_core *drc, UINT32 newpc);
+void drc_append_tentative_fixed_dispatcher(drc_core *drc, UINT32 newpc);
+void drc_append_call_debugger(drc_core *drc);
+void drc_append_standard_epilogue(drc_core *drc, INT32 cycles, INT32 pcdelta, int allow_exit);
+void drc_append_save_volatiles(drc_core *drc);
+void drc_append_restore_volatiles(drc_core *drc);
+void drc_append_save_call_restore(drc_core *drc, x86code *target, UINT32 stackadj);
+void drc_append_verify_code(drc_core *drc, void *code, UINT8 length);
+
+void drc_append_set_fp_rounding(drc_core *drc, UINT8 regindex);
+void drc_append_set_temp_fp_rounding(drc_core *drc, UINT8 rounding);
+void drc_append_restore_fp_rounding(drc_core *drc);
+
+void drc_append_set_sse_rounding(drc_core *drc, UINT8 regindex);
+void drc_append_set_temp_sse_rounding(drc_core *drc, UINT8 rounding);
+void drc_append_restore_sse_rounding(drc_core *drc);
+
+/* disassembling drc code */
+void drc_dasm(FILE *f, const void *begin, const void *end);
+
+/* x86 CPU features */
+UINT32 drc_x86_get_features(void);
+
+
+#endif /* __X86DRC_H__ */