mirror of
https://github.com/holub/mame
synced 2025-05-20 20:58:51 +03:00
156 lines
5.3 KiB
C
156 lines
5.3 KiB
C
/***************************************************************************
|
|
|
|
drcbeut.h
|
|
|
|
Utility functions for dynamic recompiling backends.
|
|
|
|
Copyright Aaron Giles
|
|
Released for general non-commercial use under the MAME license
|
|
Visit http://mamedev.org for licensing and usage restrictions.
|
|
|
|
***************************************************************************/
|
|
|
|
#pragma once
|
|
|
|
#ifndef __DRCBEUT_H__
|
|
#define __DRCBEUT_H__
|
|
|
|
#include "drcuml.h"
|
|
|
|
|
|
/***************************************************************************
|
|
TYPE DEFINITIONS
|
|
***************************************************************************/
|
|
|
|
/* callback function for forward-referenced labels */
|
|
typedef void (*drclabel_fixup_func)(void *parameter, drccodeptr labelcodeptr);
|
|
|
|
|
|
/* opaque structure representing a managed list of labels */
|
|
typedef struct _drclabel_list drclabel_list;
|
|
|
|
|
|
/* opaque structure representing a managed code map */
|
|
typedef struct _drcmap_state drcmap_state;
|
|
|
|
|
|
/* information about the hash tables used by the UML and backend */
|
|
typedef struct _drchash_state drchash_state;
|
|
struct _drchash_state
|
|
{
|
|
drc_cache * cache; /* cache where allocations come from */
|
|
int modes; /* number of modes supported */
|
|
|
|
drccodeptr nocodeptr; /* pointer to code which will handle missing entries */
|
|
|
|
UINT8 l1bits; /* bits worth of entries in l1 hash tables */
|
|
UINT8 l1shift; /* shift to apply to the PC to get the l1 hash entry */
|
|
offs_t l1mask; /* mask to apply after shifting */
|
|
UINT8 l2bits; /* bits worth of entries in l2 hash tables */
|
|
UINT8 l2shift; /* shift to apply to the PC to get the l2 hash entry */
|
|
offs_t l2mask; /* mask to apply after shifting */
|
|
|
|
drccodeptr ** emptyl1; /* pointer to empty l1 hash table */
|
|
drccodeptr * emptyl2; /* pointer to empty l2 hash table */
|
|
|
|
drccodeptr ** base[1]; /* pointer to the l1 table for each mode */
|
|
};
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
FUNCTION PROTOTYPES
|
|
***************************************************************************/
|
|
|
|
/* ----- hash table management ----- */
|
|
|
|
/* allocate memory in the cache for the hash table tracker (it auto-frees with the cache) */
|
|
drchash_state *drchash_alloc(drc_cache *cache, int modes, int addrbits, int ignorebits);
|
|
|
|
/* flush existing hash tables and create new ones */
|
|
int drchash_reset(drchash_state *drchash);
|
|
|
|
/* note the beginning of a block */
|
|
void drchash_block_begin(drchash_state *drchash, drcuml_block *block, const drcuml_instruction *instlist, UINT32 numinst);
|
|
|
|
/* note the end of a block */
|
|
void drchash_block_end(drchash_state *drchash, drcuml_block *block);
|
|
|
|
/* set the default codeptr for any empty hash entries (defaults to NULL) */
|
|
void drchash_set_default_codeptr(drchash_state *drchash, drccodeptr code);
|
|
|
|
/* set the codeptr for the given mode/pc */
|
|
int drchash_set_codeptr(drchash_state *drchash, UINT32 mode, UINT32 pc, drccodeptr code);
|
|
|
|
|
|
|
|
/* ----- code map management ----- */
|
|
|
|
/* allocate memory in the cache for the code mapper (it auto-frees with the cache) */
|
|
drcmap_state *drcmap_alloc(drc_cache *cache, UINT64 uniquevalue);
|
|
|
|
/* note the beginning of a block */
|
|
void drcmap_block_begin(drcmap_state *drcmap, drcuml_block *block);
|
|
|
|
/* note the end of a block */
|
|
void drcmap_block_end(drcmap_state *drcmap, drcuml_block *block);
|
|
|
|
/* set a map value for the given code pointer */
|
|
void drcmap_set_value(drcmap_state *drcmap, drccodeptr codebase, UINT32 mapvar, UINT32 newvalue);
|
|
|
|
/* return a map value for the given code pointer */
|
|
UINT32 drcmap_get_value(drcmap_state *drcmap, drccodeptr codebase, UINT32 mapvar);
|
|
|
|
/* return the most recently set map value */
|
|
UINT32 drcmap_get_last_value(drcmap_state *drcmap, UINT32 mapvar);
|
|
|
|
|
|
|
|
/* ----- label management ----- */
|
|
|
|
/* allocate a label list within the cache (it auto-frees with the cache) */
|
|
drclabel_list *drclabel_list_alloc(drc_cache *cache);
|
|
|
|
/* note the beginning of a block */
|
|
void drclabel_block_begin(drclabel_list *drcmap, drcuml_block *block);
|
|
|
|
/* note the end of a block */
|
|
void drclabel_block_end(drclabel_list *drcmap, drcuml_block *block);
|
|
|
|
/* find or allocate a new label; returns NULL and requests an OOB callback if undefined */
|
|
drccodeptr drclabel_get_codeptr(drclabel_list *list, drcuml_codelabel label, drclabel_fixup_func fixup, void *param);
|
|
|
|
/* set the pointer to a new label */
|
|
void drclabel_set_codeptr(drclabel_list *list, drcuml_codelabel label, drccodeptr codeptr);
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
INLINE FUNCTIONS
|
|
***************************************************************************/
|
|
|
|
/*-------------------------------------------------
|
|
drchash_get_codeptr - return the codeptr
|
|
allocated for the given mode/pc
|
|
-------------------------------------------------*/
|
|
|
|
INLINE drccodeptr drchash_get_codeptr(drchash_state *drchash, UINT32 mode, UINT32 pc)
|
|
{
|
|
assert(mode < drchash->modes);
|
|
return drchash->base[mode][(pc >> drchash->l1shift) & drchash->l1mask][(pc >> drchash->l2shift) & drchash->l2mask];
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
drchash_code_exists - return TRUE if there is
|
|
a matching hash entry for the given mode/pc
|
|
-------------------------------------------------*/
|
|
|
|
INLINE int drchash_code_exists(drchash_state *drchash, UINT32 mode, UINT32 pc)
|
|
{
|
|
return (drchash_get_codeptr(drchash, mode, pc) != drchash->nocodeptr);
|
|
}
|
|
|
|
|
|
#endif /* __DRCBEUT_H__ */
|