summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author Aaron Giles <aaron@aarongiles.com>2011-01-05 16:33:00 +0000
committer Aaron Giles <aaron@aarongiles.com>2011-01-05 16:33:00 +0000
commitc12dd417cdd53a2fde51879cebf681b9fcecf97c (patch)
treea6776f6130eabda2f8e46d639a3891c46b731f6f /src
parent7c15acffe225d87bd3387bc94c5a6a50d3215c43 (diff)
Convert drccache to C++
Diffstat (limited to 'src')
-rw-r--r--src/emu/cpu/drcbec.c12
-rw-r--r--src/emu/cpu/drcbeut.c40
-rw-r--r--src/emu/cpu/drcbeut.h8
-rw-r--r--src/emu/cpu/drcbex64.c24
-rw-r--r--src/emu/cpu/drcbex86.c20
-rw-r--r--src/emu/cpu/drccache.c465
-rw-r--r--src/emu/cpu/drccache.h196
-rw-r--r--src/emu/cpu/drcuml.c24
-rw-r--r--src/emu/cpu/drcuml.h4
-rw-r--r--src/emu/cpu/mips/mips3drc.c12
-rw-r--r--src/emu/cpu/powerpc/ppcdrc.c14
-rw-r--r--src/emu/cpu/rsp/rspdrc.c16
-rw-r--r--src/emu/cpu/sh2/sh2comn.h2
-rw-r--r--src/emu/cpu/sh2/sh2drc.c10
14 files changed, 368 insertions, 479 deletions
diff --git a/src/emu/cpu/drcbec.c b/src/emu/cpu/drcbec.c
index e5b8b9fe8df..6f6d312b367 100644
--- a/src/emu/cpu/drcbec.c
+++ b/src/emu/cpu/drcbec.c
@@ -215,7 +215,7 @@ struct _drcbe_state
device_t * device; /* CPU device we are associated with */
address_space * space[ADDRESS_SPACES]; /* pointers to CPU's address space */
drcuml_state * drcuml; /* pointer back to our owner */
- drccache * cache; /* pointer to the cache */
+ drc_cache * cache; /* pointer to the cache */
drcuml_machine_state state; /* state of the machine */
drchash_state * hash; /* hash table state */
drcmap_state * map; /* code map */
@@ -254,7 +254,7 @@ union _drcbec_instruction
***************************************************************************/
/* primary back-end callbacks */
-static drcbe_state *drcbec_alloc(drcuml_state *drcuml, drccache *cache, device_t *device, UINT32 flags, int modes, int addrbits, int ignorebits);
+static drcbe_state *drcbec_alloc(drcuml_state *drcuml, drc_cache *cache, device_t *device, UINT32 flags, int modes, int addrbits, int ignorebits);
static void drcbec_free(drcbe_state *drcbe);
static void drcbec_reset(drcbe_state *drcbe);
static int drcbec_execute(drcbe_state *state, drcuml_codehandle *entry);
@@ -340,12 +340,12 @@ extern const drcbe_interface drcbe_c_be_interface =
state
-------------------------------------------------*/
-static drcbe_state *drcbec_alloc(drcuml_state *drcuml, drccache *cache, device_t *device, UINT32 flags, int modes, int addrbits, int ignorebits)
+static drcbe_state *drcbec_alloc(drcuml_state *drcuml, drc_cache *cache, device_t *device, UINT32 flags, int modes, int addrbits, int ignorebits)
{
int spacenum;
/* allocate space in the cache for our state */
- drcbe_state *drcbe = (drcbe_state *)drccache_memory_alloc(cache, sizeof(*drcbe));
+ drcbe_state *drcbe = (drcbe_state *)cache->alloc(sizeof(*drcbe));
if (drcbe == NULL)
return NULL;
memset(drcbe, 0, sizeof(*drcbe));
@@ -414,7 +414,7 @@ static void drcbec_generate(drcbe_state *drcbe, drcuml_block *block, const drcum
drcmap_block_begin(drcbe->map, block);
/* begin codegen; fail if we can't */
- cachetop = drccache_begin_codegen(drcbe->cache, numinst * sizeof(drcbec_instruction) * 4);
+ cachetop = drcbe->cache->begin_codegen(numinst * sizeof(drcbec_instruction) * 4);
if (cachetop == NULL)
drcuml_block_abort(block);
@@ -559,7 +559,7 @@ static void drcbec_generate(drcbe_state *drcbe, drcuml_block *block, const drcum
/* complete codegen */
*cachetop = (drccodeptr)dst;
- drccache_end_codegen(drcbe->cache);
+ drcbe->cache->end_codegen();
/* tell all of our utility objects that the block is finished */
drchash_block_end(drcbe->hash, block);
diff --git a/src/emu/cpu/drcbeut.c b/src/emu/cpu/drcbeut.c
index 67fd333bed2..30e45d20d87 100644
--- a/src/emu/cpu/drcbeut.c
+++ b/src/emu/cpu/drcbeut.c
@@ -39,7 +39,7 @@ struct _drcmap_entry
/* structure describing the state of the code map */
struct _drcmap_state
{
- drccache * cache; /* pointer to the cache */
+ drc_cache * cache; /* pointer to the cache */
UINT64 uniquevalue; /* unique value used to find the table */
drcmap_entry * head; /* head of the live list */
drcmap_entry ** tailptr; /* pointer to tail of the live list */
@@ -61,7 +61,7 @@ struct _drclabel
/* structure holding a live list of labels */
struct _drclabel_list
{
- drccache * cache; /* pointer to the cache */
+ drc_cache * cache; /* pointer to the cache */
drclabel * head; /* head of the live list */
};
@@ -87,13 +87,13 @@ static void label_oob_callback(drccodeptr *codeptr, void *param1, void *param2,
with the cache)
-------------------------------------------------*/
-drchash_state *drchash_alloc(drccache *cache, int modes, int addrbits, int ignorebits)
+drchash_state *drchash_alloc(drc_cache *cache, int modes, int addrbits, int ignorebits)
{
int effaddrbits = addrbits - ignorebits;
drchash_state *drchash;
/* allocate permanent state from the cache */
- drchash = (drchash_state *)drccache_memory_alloc(cache, sizeof(*drchash) + modes * sizeof(drchash->base[0]));
+ drchash = (drchash_state *)cache->alloc(sizeof(*drchash) + modes * sizeof(drchash->base[0]));
if (drchash == NULL)
return NULL;
memset(drchash, 0, sizeof(*drchash) + modes * sizeof(drchash->base[0]));
@@ -128,7 +128,7 @@ int drchash_reset(drchash_state *drchash)
int modenum, entry;
/* allocate an empty l2 hash table */
- drchash->emptyl2 = (drccodeptr *)drccache_memory_alloc_temporary(drchash->cache, sizeof(drccodeptr) << drchash->l2bits);
+ drchash->emptyl2 = (drccodeptr *)drchash->cache->alloc_temporary(sizeof(drccodeptr) << drchash->l2bits);
if (drchash->emptyl2 == NULL)
return FALSE;
@@ -137,7 +137,7 @@ int drchash_reset(drchash_state *drchash)
drchash->emptyl2[entry] = drchash->nocodeptr;
/* allocate an empty l1 hash table */
- drchash->emptyl1 = (drccodeptr **)drccache_memory_alloc_temporary(drchash->cache, sizeof(drccodeptr *) << drchash->l1bits);
+ drchash->emptyl1 = (drccodeptr **)drchash->cache->alloc_temporary(sizeof(drccodeptr *) << drchash->l1bits);
if (drchash->emptyl1 == NULL)
return FALSE;
@@ -246,7 +246,7 @@ int drchash_set_codeptr(drchash_state *drchash, UINT32 mode, UINT32 pc, drccodep
/* copy-on-write for the l1 hash table */
if (drchash->base[mode] == drchash->emptyl1)
{
- drccodeptr **newtable = (drccodeptr **)drccache_memory_alloc_temporary(drchash->cache, sizeof(drccodeptr *) << drchash->l1bits);
+ drccodeptr **newtable = (drccodeptr **)drchash->cache->alloc_temporary(sizeof(drccodeptr *) << drchash->l1bits);
if (newtable == NULL)
return FALSE;
memcpy(newtable, drchash->emptyl1, sizeof(drccodeptr *) << drchash->l1bits);
@@ -256,7 +256,7 @@ int drchash_set_codeptr(drchash_state *drchash, UINT32 mode, UINT32 pc, drccodep
/* copy-on-write for the l2 hash table */
if (drchash->base[mode][l1] == drchash->emptyl2)
{
- drccodeptr *newtable = (drccodeptr *)drccache_memory_alloc_temporary(drchash->cache, sizeof(drccodeptr) << drchash->l2bits);
+ drccodeptr *newtable = (drccodeptr *)drchash->cache->alloc_temporary(sizeof(drccodeptr) << drchash->l2bits);
if (newtable == NULL)
return FALSE;
memcpy(newtable, drchash->emptyl2, sizeof(drccodeptr) << drchash->l2bits);
@@ -280,12 +280,12 @@ int drchash_set_codeptr(drchash_state *drchash, UINT32 mode, UINT32 pc, drccodep
cache)
-------------------------------------------------*/
-drcmap_state *drcmap_alloc(drccache *cache, UINT64 uniquevalue)
+drcmap_state *drcmap_alloc(drc_cache *cache, UINT64 uniquevalue)
{
drcmap_state *drcmap;
/* allocate permanent state from the cache */
- drcmap = (drcmap_state *)drccache_memory_alloc(cache, sizeof(*drcmap));
+ drcmap = (drcmap_state *)cache->alloc(sizeof(*drcmap));
if (drcmap == NULL)
return NULL;
memset(drcmap, 0, sizeof(*drcmap));
@@ -310,7 +310,7 @@ void drcmap_block_begin(drcmap_state *drcmap, drcuml_block *block)
{
drcmap_entry *entry = drcmap->head;
drcmap->head = entry->next;
- drccache_memory_free(drcmap->cache, entry, sizeof(*entry));
+ drcmap->cache->dealloc(entry, sizeof(*entry));
}
/* reset the tailptr and count */
@@ -340,7 +340,7 @@ void drcmap_block_end(drcmap_state *drcmap, drcuml_block *block)
return;
/* begin "code generation" aligned to an 8-byte boundary */
- top = drccache_begin_codegen(drcmap->cache, sizeof(UINT64) + sizeof(UINT32) + 2 * sizeof(UINT32) * drcmap->numvalues);
+ top = drcmap->cache->begin_codegen(sizeof(UINT64) + sizeof(UINT32) + 2 * sizeof(UINT32) * drcmap->numvalues);
if (top == NULL)
drcuml_block_abort(block);
dest = (UINT32 *)(((FPTR)*top + 7) & ~7);
@@ -408,7 +408,7 @@ void drcmap_block_end(drcmap_state *drcmap, drcuml_block *block)
/* complete codegen */
*top = (drccodeptr)dest;
- drccache_end_codegen(drcmap->cache);
+ drcmap->cache->end_codegen();
}
@@ -428,7 +428,7 @@ void drcmap_set_value(drcmap_state *drcmap, drccodeptr codebase, UINT32 mapvar,
return;
/* allocate a new entry and fill it in */
- entry = (drcmap_entry *)drccache_memory_alloc(drcmap->cache, sizeof(*entry));
+ entry = (drcmap_entry *)drcmap->cache->alloc(sizeof(*entry));
entry->next = NULL;
entry->codeptr = codebase;
entry->mapvar = mapvar - DRCUML_MAPVAR_M0;
@@ -453,7 +453,7 @@ void drcmap_set_value(drcmap_state *drcmap, drccodeptr codebase, UINT32 mapvar,
UINT32 drcmap_get_value(drcmap_state *drcmap, drccodeptr codebase, UINT32 mapvar)
{
- UINT64 *endscan = (UINT64 *)drccache_top(drcmap->cache);
+ UINT64 *endscan = (UINT64 *)drcmap->cache->top();
UINT32 varmask = 0x10 << mapvar;
drccodeptr curcode;
UINT32 result = 0;
@@ -538,12 +538,12 @@ UINT32 drcmap_get_last_value(drcmap_state *drcmap, UINT32 mapvar)
cache)
-------------------------------------------------*/
-drclabel_list *drclabel_list_alloc(drccache *cache)
+drclabel_list *drclabel_list_alloc(drc_cache *cache)
{
drclabel_list *list;
/* allocate permanent state from the cache */
- list = (drclabel_list *)drccache_memory_alloc(cache, sizeof(*list));
+ list = (drclabel_list *)cache->alloc(sizeof(*list));
if (list == NULL)
return NULL;
memset(list, 0, sizeof(*list));
@@ -590,7 +590,7 @@ drccodeptr drclabel_get_codeptr(drclabel_list *list, drcuml_codelabel label, drc
/* if no code pointer, request an OOB callback */
if (curlabel->codeptr == NULL && fixup != NULL)
- drccache_request_oob_codegen(list->cache, label_oob_callback, curlabel, (void *)fixup, param);
+ list->cache->request_oob_codegen(label_oob_callback, curlabel, (void *)fixup, param);
return curlabel->codeptr;
}
@@ -634,7 +634,7 @@ static void label_list_reset(drclabel_list *list, int fatal_on_leftovers)
fatalerror("Label %08X never defined!", label->label);
/* free the label */
- drccache_memory_free(list->cache, label, sizeof(*label));
+ list->cache->dealloc(label, sizeof(*label));
}
}
@@ -656,7 +656,7 @@ static drclabel *label_find_or_allocate(drclabel_list *list, drcuml_codelabel la
/* if none found, allocate */
if (curlabel == NULL)
{
- curlabel = (drclabel *)drccache_memory_alloc(list->cache, sizeof(*curlabel));
+ curlabel = (drclabel *)list->cache->alloc(sizeof(*curlabel));
curlabel->next = list->head;
curlabel->label = label;
curlabel->codeptr = NULL;
diff --git a/src/emu/cpu/drcbeut.h b/src/emu/cpu/drcbeut.h
index 800bb14302f..1a6f939a8bf 100644
--- a/src/emu/cpu/drcbeut.h
+++ b/src/emu/cpu/drcbeut.h
@@ -38,7 +38,7 @@ typedef struct _drcmap_state drcmap_state;
typedef struct _drchash_state drchash_state;
struct _drchash_state
{
- drccache * cache; /* cache where allocations come from */
+ drc_cache * cache; /* cache where allocations come from */
int modes; /* number of modes supported */
drccodeptr nocodeptr; /* pointer to code which will handle missing entries */
@@ -65,7 +65,7 @@ struct _drchash_state
/* ----- hash table management ----- */
/* allocate memory in the cache for the hash table tracker (it auto-frees with the cache) */
-drchash_state *drchash_alloc(drccache *cache, int modes, int addrbits, int ignorebits);
+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);
@@ -87,7 +87,7 @@ int drchash_set_codeptr(drchash_state *drchash, UINT32 mode, UINT32 pc, drccodep
/* ----- code map management ----- */
/* allocate memory in the cache for the code mapper (it auto-frees with the cache) */
-drcmap_state *drcmap_alloc(drccache *cache, UINT64 uniquevalue);
+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);
@@ -109,7 +109,7 @@ 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(drccache *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);
diff --git a/src/emu/cpu/drcbex64.c b/src/emu/cpu/drcbex64.c
index 129a98d784b..e1ac03c71f9 100644
--- a/src/emu/cpu/drcbex64.c
+++ b/src/emu/cpu/drcbex64.c
@@ -264,7 +264,7 @@ struct _drcbe_state
{
device_t * device; /* CPU device we are associated with */
drcuml_state * drcuml; /* pointer back to our owner */
- drccache * cache; /* pointer to the cache */
+ drc_cache * cache; /* pointer to the cache */
drcuml_machine_state state; /* state of the machine */
drchash_state * hash; /* hash table state */
drcmap_state * map; /* code map */
@@ -307,7 +307,7 @@ struct _drcbe_state
***************************************************************************/
/* primary back-end callbacks */
-static drcbe_state *drcbex64_alloc(drcuml_state *drcuml, drccache *cache, device_t *device, UINT32 flags, int modes, int addrbits, int ignorebits);
+static drcbe_state *drcbex64_alloc(drcuml_state *drcuml, drc_cache *cache, device_t *device, UINT32 flags, int modes, int addrbits, int ignorebits);
static void drcbex64_free(drcbe_state *drcbe);
static void drcbex64_reset(drcbe_state *drcbe);
static int drcbex64_execute(drcbe_state *drcbe, drcuml_codehandle *entry);
@@ -686,7 +686,7 @@ INLINE void emit_smart_call_m64(drcbe_state *drcbe, x86code **dst, x86code **tar
state
-------------------------------------------------*/
-static drcbe_state *drcbex64_alloc(drcuml_state *drcuml, drccache *cache, device_t *device, UINT32 flags, int modes, int addrbits, int ignorebits)
+static drcbe_state *drcbex64_alloc(drcuml_state *drcuml, drc_cache *cache, device_t *device, UINT32 flags, int modes, int addrbits, int ignorebits)
{
/* SSE control register mapping */
static const UINT32 sse_control[4] =
@@ -701,7 +701,7 @@ static drcbe_state *drcbex64_alloc(drcuml_state *drcuml, drccache *cache, device
int spacenum;
/* allocate space in the cache for our state */
- drcbe = (drcbe_state *)drccache_memory_alloc_near(cache, sizeof(*drcbe));
+ drcbe = (drcbe_state *)cache->alloc_near(sizeof(*drcbe));
if (drcbe == NULL)
return NULL;
memset(drcbe, 0, sizeof(*drcbe));
@@ -710,7 +710,7 @@ static drcbe_state *drcbex64_alloc(drcuml_state *drcuml, drccache *cache, device
drcbe->device = device;
drcbe->drcuml = drcuml;
drcbe->cache = cache;
- drcbe->rbpvalue = drccache_near(cache) + 0x80;
+ drcbe->rbpvalue = cache->near() + 0x80;
/* get address spaces and accessors */
for (spacenum = 0; spacenum < ADDRESS_SPACES; spacenum++)
@@ -722,7 +722,7 @@ static drcbe_state *drcbex64_alloc(drcuml_state *drcuml, drccache *cache, device
/* build up necessary arrays */
memcpy(drcbe->ssecontrol, sse_control, sizeof(drcbe->ssecontrol));
- drcbe->absmask32 = (UINT32 *)drccache_memory_alloc_near(cache, 16*2 + 15);
+ drcbe->absmask32 = (UINT32 *)cache->alloc_near(16*2 + 15);
drcbe->absmask32 = (UINT32 *)(((FPTR)drcbe->absmask32 + 15) & ~15);
drcbe->absmask32[0] = drcbe->absmask32[1] = drcbe->absmask32[2] = drcbe->absmask32[3] = 0x7fffffff;
drcbe->absmask64 = (UINT64 *)&drcbe->absmask32[4];
@@ -814,7 +814,7 @@ static void drcbex64_reset(drcbe_state *drcbe)
x86log_printf(drcbe->log, "\n\n===========\nCACHE RESET\n===========\n\n");
/* generate a little bit of glue code to set up the environment */
- dst = (x86code **)drccache_begin_codegen(drcbe->cache, 500);
+ dst = (x86code **)drcbe->cache->begin_codegen(500);
if (dst == NULL)
fatalerror("Out of cache space after a reset!");
@@ -874,7 +874,7 @@ static void drcbex64_reset(drcbe_state *drcbe)
x86log_disasm_code_range(drcbe->log, "nocode", drcbe->nocode, *dst);
/* finish up codegen */
- drccache_end_codegen(drcbe->cache);
+ drcbe->cache->end_codegen();
/* reset our hash tables */
drchash_reset(drcbe->hash);
@@ -913,7 +913,7 @@ static void drcbex64_generate(drcbe_state *drcbe, drcuml_block *block, const drc
drcmap_block_begin(drcbe->map, block);
/* begin codegen; fail if we can't */
- cachetop = drccache_begin_codegen(drcbe->cache, numinst * 8 * 4);
+ cachetop = drcbe->cache->begin_codegen(numinst * 8 * 4);
if (cachetop == NULL)
drcuml_block_abort(block);
@@ -953,11 +953,11 @@ static void drcbex64_generate(drcbe_state *drcbe, drcuml_block *block, const drc
/* complete codegen */
*cachetop = (drccodeptr)dst;
- drccache_end_codegen(drcbe->cache);
+ drcbe->cache->end_codegen();
/* log it */
if (drcbe->log != NULL)
- x86log_disasm_code_range(drcbe->log, (blockname == NULL) ? "Unknown block" : blockname, base, drccache_top(drcbe->cache));
+ x86log_disasm_code_range(drcbe->log, (blockname == NULL) ? "Unknown block" : blockname, base, drcbe->cache->top());
/* tell all of our utility objects that the block is finished */
drchash_block_end(drcbe->hash, block);
@@ -3340,7 +3340,7 @@ static x86code *op_exh(drcbe_state *drcbe, x86code *dst, const drcuml_instructio
else
{
emit_jcc(&dst, X86_CONDITION(inst->condition), dst + 0x7ffffff0); // jcc exception
- drccache_request_oob_codegen(drcbe->cache, fixup_exception, drcbe, dst, (void *)inst);
+ drcbe->cache->request_oob_codegen(fixup_exception, drcbe, dst, (void *)inst);
}
return dst;
}
diff --git a/src/emu/cpu/drcbex86.c b/src/emu/cpu/drcbex86.c
index d0e889213eb..6ea436f4c33 100644
--- a/src/emu/cpu/drcbex86.c
+++ b/src/emu/cpu/drcbex86.c
@@ -156,7 +156,7 @@ struct _drcbe_state
{
device_t * device; /* CPU device we are associated with */
drcuml_state * drcuml; /* pointer back to our owner */
- drccache * cache; /* pointer to the cache */
+ drc_cache * cache; /* pointer to the cache */
drcuml_machine_state state; /* state of the machine */
drchash_state * hash; /* hash table state */
drcmap_state * map; /* code map */
@@ -201,7 +201,7 @@ struct _drcbe_state
***************************************************************************/
/* primary back-end callbacks */
-static drcbe_state *drcbex86_alloc(drcuml_state *drcuml, drccache *cache, device_t *device, UINT32 flags, int modes, int addrbits, int ignorebits);
+static drcbe_state *drcbex86_alloc(drcuml_state *drcuml, drc_cache *cache, device_t *device, UINT32 flags, int modes, int addrbits, int ignorebits);
static void drcbex86_free(drcbe_state *drcbe);
static void drcbex86_reset(drcbe_state *drcbe);
static int drcbex86_execute(drcbe_state *drcbe, drcuml_codehandle *entry);
@@ -614,13 +614,13 @@ INLINE void track_resolve_link(drcbe_state *drcbe, x86code **destptr, const emit
state
-------------------------------------------------*/
-static drcbe_state *drcbex86_alloc(drcuml_state *drcuml, drccache *cache, device_t *device, UINT32 flags, int modes, int addrbits, int ignorebits)
+static drcbe_state *drcbex86_alloc(drcuml_state *drcuml, drc_cache *cache, device_t *device, UINT32 flags, int modes, int addrbits, int ignorebits)
{
int opnum, regnum, entry, spacenum;
drcbe_state *drcbe;
/* allocate space in the cache for our state */
- drcbe = (drcbe_state *)drccache_memory_alloc(cache, sizeof(*drcbe));
+ drcbe = (drcbe_state *)cache->alloc(sizeof(*drcbe));
if (drcbe == NULL)
return NULL;
memset(drcbe, 0, sizeof(*drcbe));
@@ -722,7 +722,7 @@ static void drcbex86_reset(drcbe_state *drcbe)
x86log_printf(drcbe->log, "\n\n===========\nCACHE RESET\n===========\n\n");
/* generate a little bit of glue code to set up the environment */
- dst = (x86code **)drccache_begin_codegen(drcbe->cache, 500);
+ dst = (x86code **)drcbe->cache->begin_codegen(500);
if (dst == NULL)
fatalerror("Out of cache space after a reset!");
@@ -850,7 +850,7 @@ static void drcbex86_reset(drcbe_state *drcbe)
x86log_disasm_code_range(drcbe->log, "restore", drcbe->restore, *dst);
/* finish up codegen */
- drccache_end_codegen(drcbe->cache);
+ drcbe->cache->end_codegen();
drcbe->logged_common = TRUE;
/* reset our hash tables */
@@ -890,7 +890,7 @@ static void drcbex86_generate(drcbe_state *drcbe, drcuml_block *block, const drc
drcmap_block_begin(drcbe->map, block);
/* begin codegen; fail if we can't */
- cachetop = drccache_begin_codegen(drcbe->cache, numinst * 8 * 4);
+ cachetop = drcbe->cache->begin_codegen(numinst * 8 * 4);
if (cachetop == NULL)
drcuml_block_abort(block);
@@ -930,11 +930,11 @@ static void drcbex86_generate(drcbe_state *drcbe, drcuml_block *block, const drc
/* complete codegen */
*cachetop = (drccodeptr)dst;
- drccache_end_codegen(drcbe->cache);
+ drcbe->cache->end_codegen();
/* log it */
if (drcbe->log != NULL)
- x86log_disasm_code_range(drcbe->log, (blockname == NULL) ? "Unknown block" : blockname, base, drccache_top(drcbe->cache));
+ x86log_disasm_code_range(drcbe->log, (blockname == NULL) ? "Unknown block" : blockname, base, drcbe->cache->top());
/* tell all of our utility objects that the block is finished */
drchash_block_end(drcbe->hash, block);
@@ -3546,7 +3546,7 @@ static x86code *op_exh(drcbe_state *drcbe, x86code *dst, const drcuml_instructio
else
{
emit_jcc(&dst, X86_CONDITION(inst->condition), 0); // jcc exception
- drccache_request_oob_codegen(drcbe->cache, fixup_exception, drcbe, dst, (void *)inst);
+ drcbe->cache->request_oob_codegen(fixup_exception, drcbe, dst, (void *)inst);
}
return dst;
}
diff --git a/src/emu/cpu/drccache.c b/src/emu/cpu/drccache.c
index fbb424b15ed..462ab48ff5d 100644
--- a/src/emu/cpu/drccache.c
+++ b/src/emu/cpu/drccache.c
@@ -1,12 +1,39 @@
/***************************************************************************
- drccache.h
+ drccache.c
Universal dynamic recompiler cache management.
+****************************************************************************
+
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.
***************************************************************************/
@@ -15,403 +42,241 @@
-/***************************************************************************
- CONSTANTS
-***************************************************************************/
-
-/* largest block of code that can be generated at once */
-#define CODEGEN_MAX_BYTES 65536
-
-/* minimum alignment, in bytes (must be power of 2) */
-#define CACHE_ALIGNMENT 8
-
-/* largest permanent allocation we allow */
-#define MAX_PERMANENT_ALLOC 1024
-
-/* size of "near" area at the base of the cache */
-#define NEAR_CACHE_SIZE 65536
-
-
-
-/***************************************************************************
- MACROS
-***************************************************************************/
+//**************************************************************************
+// MACROS
+//**************************************************************************
-/* ensure that all memory allocated is aligned to an 8-byte boundary */
+// ensure that all memory allocated is aligned to an 8-byte boundary
#define ALIGN_PTR_UP(p) ((void *)(((FPTR)(p) + (CACHE_ALIGNMENT - 1)) & ~(CACHE_ALIGNMENT - 1)))
#define ALIGN_PTR_DOWN(p) ((void *)((FPTR)(p) & ~(CACHE_ALIGNMENT - 1)))
-/***************************************************************************
- TYPE DEFINITIONS
-***************************************************************************/
-
-/* out-of-bounds codegen handlers */
-typedef struct _oob_handler oob_handler;
-struct _oob_handler
-{
- oob_handler * next; /* next handler */
- drccache_oob_func callback; /* callback function */
- void * param1; /* 1st pointer parameter */
- void * param2; /* 2nd pointer parameter */
- void * param3; /* 3rd pointer parameter */
-};
-
-
-/* a linked list of free items */
-typedef struct _free_link free_link;
-struct _free_link
-{
- free_link * next; /* pointer to the next guy */
-};
-
-
-/* cache state */
-struct _drccache
-{
- /* core parameters */
- drccodeptr near; /* pointer to the near part of the cache */
- drccodeptr neartop; /* top of the near part of the cache */
- drccodeptr base; /* base pointer to the compiler cache */
- drccodeptr top; /* current top of cache */
- drccodeptr end; /* end of cache memory */
- drccodeptr codegen; /* start of generated code */
- size_t size; /* size of the cache in bytes */
-
- /* oob management */
- oob_handler * ooblist; /* list of oob handlers */
- oob_handler ** oobtail; /* pointer to tail oob pointer */
-
- /* free lists */
- free_link * free[MAX_PERMANENT_ALLOC / CACHE_ALIGNMENT];
- free_link * nearfree[MAX_PERMANENT_ALLOC / CACHE_ALIGNMENT];
-};
-
-
-
-/***************************************************************************
- INITIALIZATION/TEARDOWN
-***************************************************************************/
-
-/*-------------------------------------------------
- drccache_alloc - allocate the cache itself
--------------------------------------------------*/
-
-drccache *drccache_alloc(size_t bytes)
-{
- drccache cache, *cacheptr;
-
- assert(bytes >= sizeof(cache) + NEAR_CACHE_SIZE);
-
- /* build a local structure first */
- memset(&cache, 0, sizeof(cache));
- cache.near = (drccodeptr)osd_alloc_executable(bytes);
- cache.neartop = cache.near;
- cache.base = cache.near + NEAR_CACHE_SIZE;
- cache.top = cache.base;
- cache.end = cache.near + bytes;
- cache.size = bytes;
-
- /* now allocate the cache structure itself from that */
- cacheptr = (drccache *)drccache_memory_alloc(&cache, sizeof(cache));
- *cacheptr = cache;
-
- /* return the allocated result */
- return cacheptr;
-}
-
-
-/*-------------------------------------------------
- drccache_free - free the cache
--------------------------------------------------*/
-
-void drccache_free(drccache *cache)
-{
- /* release the memory; this includes the cache object itself */
- osd_free_executable(cache->near, cache->size);
-}
-
-
-
-/***************************************************************************
- CACHE INFORMATION
-***************************************************************************/
-
-/*-------------------------------------------------
- drccache_contains_pointer - return true if a
- pointer is within the cache
--------------------------------------------------*/
-
-int drccache_contains_pointer(drccache *cache, const void *ptr)
-{
- return ((const drccodeptr)ptr >= cache->near && (const drccodeptr)ptr < cache->near + cache->size);
-}
-
+//**************************************************************************
+// DRC CACHE
+//**************************************************************************
-/*-------------------------------------------------
- drccache_contains_near_pointer - return true
- if a pointer is within the cache
--------------------------------------------------*/
+//-------------------------------------------------
+// drc_cache - constructor
+//-------------------------------------------------
-int drccache_contains_near_pointer(drccache *cache, const void *ptr)
+drc_cache::drc_cache(size_t bytes)
+ : m_near((drccodeptr)osd_alloc_executable(bytes)),
+ m_neartop(m_near),
+ m_base(m_near + NEAR_CACHE_SIZE),
+ m_top(m_base),
+ m_end(m_near + bytes),
+ m_codegen(0),
+ m_size(bytes)
{
- return ((const drccodeptr)ptr >= cache->near && (const drccodeptr)ptr < cache->neartop);
+ memset(m_free, 0, sizeof(m_free));
+ memset(m_nearfree, 0, sizeof(m_nearfree));
}
-/*-------------------------------------------------
- drccache_near - return a pointer to the near
- part of the cache
--------------------------------------------------*/
+//-------------------------------------------------
+// ~drc_cache - destructor
+//-------------------------------------------------
-drccodeptr drccache_near(drccache *cache)
+drc_cache::~drc_cache()
{
- return cache->near;
+ // release the memory
+ osd_free_executable(m_near, m_size);
}
-/*-------------------------------------------------
- drccache_base - return a pointer to the base
- of the cache
--------------------------------------------------*/
-
-drccodeptr drccache_base(drccache *cache)
-{
- return cache->base;
-}
+//-------------------------------------------------
+// flush - flush the cache contents
+//-------------------------------------------------
-/*-------------------------------------------------
- drccache_top - return the current top of the
- cache
--------------------------------------------------*/
-
-drccodeptr drccache_top(drccache *cache)
+void drc_cache::flush()
{
- return cache->top;
-}
-
+ // can't flush in the middle of codegen
+ assert(m_codegen == NULL);
-
-/***************************************************************************
- MEMORY MANAGEMENT
-***************************************************************************/
-
-/*-------------------------------------------------
- drccache_flush - flush the cache contents
--------------------------------------------------*/
-
-void drccache_flush(drccache *cache)
-{
- /* can't flush in the middle of codegen */
- assert(cache->codegen == NULL);
-
- /* just reset the top back to the base and re-seed */
- cache->top = cache->base;
+ // just reset the top back to the base and re-seed
+ m_top = m_base;
}
-/*-------------------------------------------------
- drccache_memory_alloc - allocate permanent
- memory from the cache
--------------------------------------------------*/
+//-------------------------------------------------
+// alloc - allocate permanent memory from the
+// cache
+//-------------------------------------------------
-void *drccache_memory_alloc(drccache *cache, size_t bytes)
+void *drc_cache::alloc(size_t bytes)
{
- drccodeptr ptr;
-
assert(bytes > 0);
- /* pick first from the free list */
+ // pick first from the free list
if (bytes < MAX_PERMANENT_ALLOC)
{
- free_link **linkptr = &cache->free[(bytes + CACHE_ALIGNMENT - 1) / CACHE_ALIGNMENT];
+ free_link **linkptr = &m_free[(bytes + CACHE_ALIGNMENT - 1) / CACHE_ALIGNMENT];
free_link *link = *linkptr;
if (link != NULL)
{
- *linkptr = link->next;
+ *linkptr = link->m_next;
return link;
}
}
- /* if no space, we just fail */
- ptr = (drccodeptr)ALIGN_PTR_DOWN(cache->end - bytes);
- if (cache->top > ptr)
+ // if no space, we just fail
+ drccodeptr ptr = (drccodeptr)ALIGN_PTR_DOWN(m_end - bytes);
+ if (m_top > ptr)
return NULL;
- /* otherwise update the end of the cache */
- cache->end = ptr;
+ // otherwise update the end of the cache
+ m_end = ptr;
return ptr;
}
-/*-------------------------------------------------
- drccache_memory_alloc_near - allocate
- permanent memory from the near part of the
- cache
--------------------------------------------------*/
+//-------------------------------------------------
+// alloc_near - allocate permanent memory from
+// the near part of the cache
+//-------------------------------------------------
-void *drccache_memory_alloc_near(drccache *cache, size_t bytes)
+void *drc_cache::alloc_near(size_t bytes)
{
- drccodeptr ptr;
-
assert(bytes > 0);
- /* pick first from the free list */
+ // pick first from the free list
if (bytes < MAX_PERMANENT_ALLOC)
{
- free_link **linkptr = &cache->nearfree[(bytes + CACHE_ALIGNMENT - 1) / CACHE_ALIGNMENT];
+ free_link **linkptr = &m_nearfree[(bytes + CACHE_ALIGNMENT - 1) / CACHE_ALIGNMENT];
free_link *link = *linkptr;
if (link != NULL)
{
- *linkptr = link->next;
+ *linkptr = link->m_next;
return link;
}
}
- /* if no space, we just fail */
- ptr = (drccodeptr)ALIGN_PTR_UP(cache->neartop);
- if (ptr + bytes > cache->base)
+ // if no space, we just fail
+ drccodeptr ptr = (drccodeptr)ALIGN_PTR_UP(m_neartop);
+ if (ptr + bytes > m_base)
return NULL;
- /* otherwise update the top of the near part of the cache */
- cache->neartop = ptr + bytes;
+ // otherwise update the top of the near part of the cache
+ m_neartop = ptr + bytes;
return ptr;
}
-/*-------------------------------------------------
- drccache_memory_free - release permanent
- memory allocated from the cache
--------------------------------------------------*/
+//-------------------------------------------------
+// alloc_temporary - allocate temporary memory
+// from the cache
+//-------------------------------------------------
-void drccache_memory_free(drccache *cache, void *memory, size_t bytes)
+void *drc_cache::alloc_temporary(size_t bytes)
{
- free_link **linkptr;
- free_link *link = (free_link *)memory;
+ // can't allocate in the middle of codegen
+ assert(m_codegen == NULL);
- assert(bytes < MAX_PERMANENT_ALLOC);
- assert(((drccodeptr)memory >= cache->near && (drccodeptr)memory < cache->base) || ((drccodeptr)memory >= cache->end && (drccodeptr)memory < cache->near + cache->size));
-
- /* determine which free list to add to */
- if ((drccodeptr)memory < cache->base)
- linkptr = &cache->nearfree[(bytes + CACHE_ALIGNMENT - 1) / CACHE_ALIGNMENT];
- else
- linkptr = &cache->free[(bytes + CACHE_ALIGNMENT - 1) / CACHE_ALIGNMENT];
+ // if no space, we just fail
+ drccodeptr ptr = m_top;
+ if (ptr + bytes >= m_end)
+ return NULL;
- /* link is into the free list for our size */
- link->next = *linkptr;
- *linkptr = link;
+ // otherwise, update the cache top
+ m_top = (drccodeptr)ALIGN_PTR_UP(ptr + bytes);
+ return ptr;
}
-/*-------------------------------------------------
- drccache_memory_alloc_temporary - allocate
- temporary memory from the cache
--------------------------------------------------*/
+//-------------------------------------------------
+// free - release permanent memory allocated from
+// the cache
+//-------------------------------------------------
-void *drccache_memory_alloc_temporary(drccache *cache, size_t bytes)
+void drc_cache::dealloc(void *memory, size_t bytes)
{
- drccodeptr ptr = cache->top;
-
- /* can't allocate in the middle of codegen */
- assert(cache->codegen == NULL);
+ assert(bytes < MAX_PERMANENT_ALLOC);
+ assert(((drccodeptr)memory >= m_near && (drccodeptr)memory < m_base) || ((drccodeptr)memory >= m_end && (drccodeptr)memory < m_near + m_size));
- /* if no space, we just fail */
- if (ptr + bytes >= cache->end)
- return NULL;
+ // determine which free list to add to
+ free_link **linkptr;
+ if ((drccodeptr)memory < m_base)
+ linkptr = &m_nearfree[(bytes + CACHE_ALIGNMENT - 1) / CACHE_ALIGNMENT];
+ else
+ linkptr = &m_free[(bytes + CACHE_ALIGNMENT - 1) / CACHE_ALIGNMENT];
- /* otherwise, update the cache top */
- cache->top = (drccodeptr)ALIGN_PTR_UP(ptr + bytes);
- return ptr;
+ // link is into the free list for our size
+ free_link *link = (free_link *)memory;
+ link->m_next = *linkptr;
+ *linkptr = link;
}
+//-------------------------------------------------
+// begin_codegen - begin code generation
+//-------------------------------------------------
-/***************************************************************************
- CODE GENERATION
-***************************************************************************/
-
-/*-------------------------------------------------
- drccache_begin_codegen - begin code
- generation
--------------------------------------------------*/
-
-drccodeptr *drccache_begin_codegen(drccache *cache, UINT32 reserve_bytes)
+drccodeptr *drc_cache::begin_codegen(UINT32 reserve_bytes)
{
- drccodeptr ptr = cache->top;
+ // can't restart in the middle of codegen
+ assert(m_codegen == NULL);
+ assert(m_ooblist == NULL);
- /* can't restart in the middle of codegen */
- assert(cache->codegen == NULL);
- assert(cache->ooblist == NULL);
-
- /* if still no space, we just fail */
- if (ptr + reserve_bytes >= cache->end)
+ // if still no space, we just fail
+ drccodeptr ptr = m_top;
+ if (ptr + reserve_bytes >= m_end)
return NULL;
- /* otherwise, return a pointer to the cache top */
- cache->codegen = cache->top;
- cache->oobtail = &cache->ooblist;
- return &cache->top;
+ // otherwise, return a pointer to the cache top
+ m_codegen = m_top;
+ return &m_top;
}
-/*-------------------------------------------------
- drccache_end_codegen - complete code
- generation
--------------------------------------------------*/
+//-------------------------------------------------
+// end_codegen - complete code generation
+//-------------------------------------------------
-drccodeptr drccache_end_codegen(drccache *cache)
+drccodeptr drc_cache::end_codegen()
{
- drccodeptr result = cache->codegen;
+ drccodeptr result = m_codegen;
- /* run the OOB handlers */
- while (cache->ooblist != NULL)
+ // run the OOB handlers
+ oob_handler *oob;
+ while ((oob = m_ooblist.detach_head()) != NULL)
{
- /* remove us from the list */
- oob_handler *oob = cache->ooblist;
- cache->ooblist = oob->next;
-
- /* call the callback */
- (*oob->callback)(&cache->top, oob->param1, oob->param2, oob->param3);
- assert(cache->top - cache->codegen < CODEGEN_MAX_BYTES);
+ // call the callback
+ (*oob->m_callback)(&m_top, oob->m_param1, oob->m_param2, oob->m_param3);
+ assert(m_top - m_codegen < CODEGEN_MAX_BYTES);
- /* release our memory */
- drccache_memory_free(cache, oob, sizeof(*oob));
+ // release our memory
+ dealloc(oob, sizeof(*oob));
}
- /* update the cache top */
- cache->top = (drccodeptr)ALIGN_PTR_UP(cache->top);
- cache->codegen = NULL;
+ // update the cache top
+ m_top = (drccodeptr)ALIGN_PTR_UP(m_top);
+ m_codegen = NULL;
return result;
}
-/*-------------------------------------------------
- drccache_request_oob_codegen - request
- callback for out-of-band codegen
--------------------------------------------------*/
+//-------------------------------------------------
+// request_oob_codegen - request callback for
+// out-of-band codegen
+//-------------------------------------------------
-void drccache_request_oob_codegen(drccache *cache, drccache_oob_func callback, void *param1, void *param2, void *param3)
+void drc_cache::request_oob_codegen(oob_func callback, void *param1, void *param2, void *param3)
{
- oob_handler *oob;
-
- assert(cache->codegen != NULL);
+ assert(m_codegen != NULL);
- /* pull an item from the free list */
- oob = (oob_handler *)drccache_memory_alloc(cache, sizeof(*oob));
+ // pull an item from the free list
+ oob_handler *oob = (oob_handler *)alloc(sizeof(*oob));
assert(oob != NULL);
- /* fill it in */
- oob->next = NULL;
- oob->callback = callback;
- oob->param1 = param1;
- oob->param2 = param2;
- oob->param3 = param3;
+ // fill it in
+ oob->m_callback = callback;
+ oob->m_param1 = param1;
+ oob->m_param2 = param2;
+ oob->m_param3 = param3;
- /* add to the tail */
- *cache->oobtail = oob;
- cache->oobtail = &oob->next;
+ // add to the tail
+ m_ooblist.append(*oob);
}
diff --git a/src/emu/cpu/drccache.h b/src/emu/cpu/drccache.h
index 130436b1411..fe2475c272d 100644
--- a/src/emu/cpu/drccache.h
+++ b/src/emu/cpu/drccache.h
@@ -4,9 +4,36 @@
Universal dynamic recompiler cache management.
+****************************************************************************
+
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.
***************************************************************************/
@@ -17,93 +44,98 @@
-/***************************************************************************
- MACROS
-***************************************************************************/
+//**************************************************************************
+// MACROS
+//**************************************************************************
-/* ensure that a given pointer is within the cache boundaries */
-#define assert_in_cache(c,p) assert(drccache_contains_pointer(c, p))
-#define assert_in_near_cache(c,p) assert(drccache_contains_near_pointer(c, p))
+// ensure that a given pointer is within the cache boundaries
+#define assert_in_cache(c,p) assert((c)->contains_pointer(p))
+#define assert_in_near_cache(c,p) assert((c)->contains_near_pointer(p))
-/***************************************************************************
- TYPE DEFINITIONS
-***************************************************************************/
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
-/* generic code pointer */
+// generic code pointer
typedef UINT8 *drccodeptr;
-/* opaque cache state */
-typedef struct _drccache drccache;
-
-/* out of band codegen callback */
-typedef void (*drccache_oob_func)(drccodeptr *codeptr, void *param1, void *param2, void *param3);
-
-
-
-/***************************************************************************
- FUNCTION PROTOTYPES
-***************************************************************************/
-
-/* ----- initialization/teardown ----- */
-
-/* allocate the cache itself */
-drccache *drccache_alloc(size_t bytes);
-
-/* free the cache */
-void drccache_free(drccache *cache);
-
-
-
-/* ----- cache information ----- */
-
-/* return true if a pointer is within the cache */
-int drccache_contains_pointer(drccache *cache, const void *ptr);
-
-/* return true if a pointer is within the near area of the cache */
-int drccache_contains_near_pointer(drccache *cache, const void *ptr);
-
-/* return a pointer to the near part of the cache */
-drccodeptr drccache_near(drccache *cache);
-
-/* return a pointer to the base of the cache, which is where code generation starts */
-drccodeptr drccache_base(drccache *cache);
-
-/* return the current top of the cache, which is where the next code will be generated */
-drccodeptr drccache_top(drccache *cache);
-
-
-
-/* ----- memory management ----- */
-
-/* flush the cache contents */
-void drccache_flush(drccache *cache);
-
-/* allocate permanent memory from the cache */
-void *drccache_memory_alloc(drccache *cache, size_t bytes);
-
-/* allocate permanent memory from the near portion of the cache */
-void *drccache_memory_alloc_near(drccache *cache, size_t bytes);
-
-/* release permanent memory allocated from the cache */
-void drccache_memory_free(drccache *cache, void *memory, size_t bytes);
-
-/* allocate temporary memory from the cache (released on a reset) */
-void *drccache_memory_alloc_temporary(drccache *cache, size_t bytes);
-
-
-
-/* ----- code generation ----- */
-
-/* begin code generation */
-drccodeptr *drccache_begin_codegen(drccache *cache, UINT32 reserve_bytes);
-
-/* complete code generation */
-drccodeptr drccache_end_codegen(drccache *cache);
-
-/* request callback for out-of-band codegen */
-void drccache_request_oob_codegen(drccache *cache, drccache_oob_func callback, void *param1, void *param2, void *param3);
+// drc_cache
+class drc_cache
+{
+public:
+ // out of band codegen callback
+ typedef void (*oob_func)(drccodeptr *codeptr, void *param1, void *param2, void *param3);
+
+ // construction/destruction
+ drc_cache(size_t bytes);
+ ~drc_cache();
+
+ // getters
+ drccodeptr near() const { return m_near; }
+ drccodeptr base() const { return m_base; }
+ drccodeptr top() const { return m_top; }
+
+ // pointer checking
+ bool contains_pointer(const void *ptr) const { return ((const drccodeptr)ptr >= m_near && (const drccodeptr)ptr < m_near + m_size); }
+ bool contains_near_pointer(const void *ptr) const { return ((const drccodeptr)ptr >= m_near && (const drccodeptr)ptr < m_neartop); }
+
+ // memory management
+ void flush();
+ void *alloc(size_t bytes);
+ void *alloc_near(size_t bytes);
+ void *alloc_temporary(size_t bytes);
+ void dealloc(void *memory, size_t bytes);
+
+ // codegen helpers
+ drccodeptr *begin_codegen(UINT32 reserve_bytes);
+ drccodeptr end_codegen();
+ void request_oob_codegen(oob_func callback, void *param1 = NULL, void *param2 = NULL, void *param3 = NULL);
+
+private:
+ // largest block of code that can be generated at once
+ static const size_t CODEGEN_MAX_BYTES = 65536;
+
+ // minimum alignment, in bytes (must be power of 2)
+ static const size_t CACHE_ALIGNMENT = 8;
+
+ // largest permanent allocation we allow
+ static const size_t MAX_PERMANENT_ALLOC = 1024;
+
+ // size of "near" area at the base of the cache
+ static const size_t NEAR_CACHE_SIZE = 65536;
+
+ // core parameters
+ drccodeptr m_near; // pointer to the near part of the cache
+ drccodeptr m_neartop; // top of the near part of the cache
+ drccodeptr m_base; // base pointer to the compiler cache
+ drccodeptr m_top; // current top of cache
+ drccodeptr m_end; // end of cache memory
+ drccodeptr m_codegen; // start of generated code
+ size_t m_size; // size of the cache in bytes
+
+ // oob management
+ struct oob_handler
+ {
+ oob_handler *next() const { return m_next; }
+
+ oob_handler * m_next; // next handler
+ oob_func m_callback; // callback function
+ void * m_param1; // 1st pointer parameter
+ void * m_param2; // 2nd pointer parameter
+ void * m_param3; // 3rd pointer parameter
+ };
+ simple_list<oob_handler> m_ooblist; // list of oob handlers
+
+ // free lists
+ struct free_link
+ {
+ free_link * m_next; // pointer to the next guy
+ };
+ free_link * m_free[MAX_PERMANENT_ALLOC / CACHE_ALIGNMENT];
+ free_link * m_nearfree[MAX_PERMANENT_ALLOC / CACHE_ALIGNMENT];
+};
#endif /* __DRCCACHE_H__ */
diff --git a/src/emu/cpu/drcuml.c b/src/emu/cpu/drcuml.c
index c558728827c..27f50bb121d 100644
--- a/src/emu/cpu/drcuml.c
+++ b/src/emu/cpu/drcuml.c
@@ -136,7 +136,7 @@ struct _drcuml_symbol
struct _drcuml_state
{
device_t * device; /* CPU device we are associated with */
- drccache * cache; /* pointer to the codegen cache */
+ drc_cache * cache; /* pointer to the codegen cache */
drcuml_block * blocklist; /* list of active blocks */
const drcbe_interface * beintf; /* backend interface pointer */
drcbe_state * bestate; /* pointer to the back-end state */
@@ -538,13 +538,13 @@ INLINE void convert_to_mov_param(drcuml_instruction *inst, int pnum)
generator and initialize the back-end
-------------------------------------------------*/
-drcuml_state *drcuml_alloc(device_t *device, drccache *cache, UINT32 flags, int modes, int addrbits, int ignorebits)
+drcuml_state *drcuml_alloc(device_t *device, drc_cache *cache, UINT32 flags, int modes, int addrbits, int ignorebits)
{
drcuml_state *drcuml;
int opnum;
/* allocate state */
- drcuml = (drcuml_state *)drccache_memory_alloc(cache, sizeof(*drcuml));
+ drcuml = (drcuml_state *)cache->alloc(sizeof(*drcuml));
if (drcuml == NULL)
return NULL;
memset(drcuml, 0, sizeof(*drcuml));
@@ -597,7 +597,7 @@ void drcuml_reset(drcuml_state *drcuml)
jmp_buf errorbuf;
/* flush the cache */
- drccache_flush(drcuml->cache);
+ drcuml->cache->flush();
/* if we error here, we are screwed */
if (setjmp(errorbuf) != 0)
@@ -946,16 +946,16 @@ drcuml_codehandle *drcuml_handle_alloc(drcuml_state *drcuml, const char *name)
char *string;
/* allocate space for a copy of the string */
- string = (char *)drccache_memory_alloc(drcuml->cache, strlen(name) + 1);
+ string = (char *)drcuml->cache->alloc(strlen(name) + 1);
if (string == NULL)
return NULL;
strcpy(string, name);
/* allocate a new handle info */
- handle = (drcuml_codehandle *)drccache_memory_alloc_near(drcuml->cache, sizeof(*handle));
+ handle = (drcuml_codehandle *)drcuml->cache->alloc_near(sizeof(*handle));
if (handle == NULL)
{
- drccache_memory_free(drcuml->cache, string, strlen(name) + 1);
+ drcuml->cache->dealloc(string, strlen(name) + 1);
return NULL;
}
memset(handle, 0, sizeof(*handle));
@@ -1113,7 +1113,7 @@ void drcuml_add_comment(drcuml_block *block, const char *format, ...)
va_end(va);
/* allocate space in the cache to hold the comment */
- comment = (char *)drccache_memory_alloc_temporary(block->drcuml->cache, strlen(buffer) + 1);
+ comment = (char *)block->drcuml->cache->alloc_temporary(strlen(buffer) + 1);
if (comment == NULL)
return;
strcpy(comment, buffer);
@@ -1263,8 +1263,8 @@ void drcuml_disasm(const drcuml_instruction *inst, char *buffer, drcuml_state *d
}
/* cache memory */
- else if (drcuml != NULL && drccache_contains_pointer(drcuml->cache, (void *)(FPTR)param->value))
- dest += sprintf(dest, "[+$%X]", (UINT32)(FPTR)((drccodeptr)(FPTR)param->value - drccache_near(drcuml->cache)));
+ else if (drcuml != NULL && drcuml->cache->contains_pointer((void *)(FPTR)param->value))
+ dest += sprintf(dest, "[+$%X]", (UINT32)(FPTR)((drccodeptr)(FPTR)param->value - drcuml->cache->near()));
/* general memory */
else
@@ -2181,7 +2181,7 @@ static void bevalidate_execute(drcuml_state *drcuml, drcuml_codehandle **handles
int numparams;
/* allocate memory for parameters */
- parammem = (UINT64 *)drccache_memory_alloc_near(drcuml->cache, sizeof(UINT64) * (ARRAY_LENGTH(test->param) + 1));
+ parammem = (UINT64 *)drcuml->cache->alloc_near(sizeof(UINT64) * (ARRAY_LENGTH(test->param) + 1));
/* flush the cache */
drcuml_reset(drcuml);
@@ -2237,7 +2237,7 @@ static void bevalidate_execute(drcuml_state *drcuml, drcuml_codehandle **handles
bevalidate_verify_state(drcuml, &istate, &fstate, test, *(UINT32 *)&parammem[ARRAY_LENGTH(test->param)], params, &testinst, handles[1]->code, handles[2]->code, flagmask);
/* free memory */
- drccache_memory_free(drcuml->cache, parammem, sizeof(UINT64) * (ARRAY_LENGTH(test->param) + 1));
+ drcuml->cache->dealloc(parammem, sizeof(UINT64) * (ARRAY_LENGTH(test->param) + 1));
}
diff --git a/src/emu/cpu/drcuml.h b/src/emu/cpu/drcuml.h
index 5c6ad1ac563..9e2d5bc9ac4 100644
--- a/src/emu/cpu/drcuml.h
+++ b/src/emu/cpu/drcuml.h
@@ -417,7 +417,7 @@ struct _drcbe_info
/* typedefs for back-end callback functions */
-typedef drcbe_state *(*drcbe_alloc_func)(drcuml_state *drcuml, drccache *cache, device_t *device, UINT32 flags, int modes, int addrbits, int ignorebits);
+typedef drcbe_state *(*drcbe_alloc_func)(drcuml_state *drcuml, drc_cache *cache, device_t *device, UINT32 flags, int modes, int addrbits, int ignorebits);
typedef void (*drcbe_free_func)(drcbe_state *state);
typedef void (*drcbe_reset_func)(drcbe_state *state);
typedef int (*drcbe_execute_func)(drcbe_state *state, drcuml_codehandle *entry);
@@ -448,7 +448,7 @@ struct _drcbe_interface
/* ----- initialization/teardown ----- */
/* allocate state for the code generator and initialize the back-end */
-drcuml_state *drcuml_alloc(device_t *device, drccache *cache, UINT32 flags, int modes, int addrbits, int ignorebits);
+drcuml_state *drcuml_alloc(device_t *device, drc_cache *cache, UINT32 flags, int modes, int addrbits, int ignorebits);
/* return information about the back-end */
void drcuml_get_backend_info(drcuml_state *drcuml, drcbe_info *info);
diff --git a/src/emu/cpu/mips/mips3drc.c b/src/emu/cpu/mips/mips3drc.c
index 86e12e91a9d..7b84f95aee5 100644
--- a/src/emu/cpu/mips/mips3drc.c
+++ b/src/emu/cpu/mips/mips3drc.c
@@ -184,7 +184,7 @@ struct _compiler_state
struct _mips3imp_state
{
/* core state */
- drccache * cache; /* pointer to the DRC code cache */
+ drc_cache * cache; /* pointer to the DRC code cache */
drcuml_state * drcuml; /* DRC UML generator state */
mips3_frontend * drcfe; /* pointer to the DRC front-end state */
UINT32 drcoptions; /* configurable DRC options */
@@ -388,25 +388,25 @@ INLINE void save_fast_iregs(mips3_state *mips3, drcuml_block *block)
static void mips3_init(mips3_flavor flavor, int bigendian, legacy_cpu_device *device, device_irq_callback irqcallback)
{
mips3_state *mips3;
- drccache *cache;
+ drc_cache *cache;
drcbe_info beinfo;
UINT32 flags = 0;
int regnum;
/* allocate enough space for the cache and the core */
- cache = (drccache *)drccache_alloc(CACHE_SIZE + sizeof(*mips3));
+ cache = auto_alloc(device->machine, drc_cache(CACHE_SIZE + sizeof(*mips3)));
if (cache == NULL)
fatalerror("Unable to allocate cache of size %d", (UINT32)(CACHE_SIZE + sizeof(*mips3)));
/* allocate the core memory */
- *(mips3_state **)device->token() = mips3 = (mips3_state *)drccache_memory_alloc_near(cache, sizeof(*mips3));
+ *(mips3_state **)device->token() = mips3 = (mips3_state *)cache->alloc_near(sizeof(*mips3));
memset(mips3, 0, sizeof(*mips3));
/* initialize the core */
mips3com_init(mips3, flavor, bigendian, device, irqcallback);
/* allocate the implementation-specific state from the full cache */
- mips3->impstate = (mips3imp_state *)drccache_memory_alloc_near(cache, sizeof(*mips3->impstate));
+ mips3->impstate = (mips3imp_state *)cache->alloc_near(sizeof(*mips3->impstate));
memset(mips3->impstate, 0, sizeof(*mips3->impstate));
mips3->impstate->cache = cache;
@@ -566,7 +566,7 @@ static CPU_EXIT( mips3 )
/* clean up the DRC */
auto_free(device->machine, mips3->impstate->drcfe);
drcuml_free(mips3->impstate->drcuml);
- drccache_free(mips3->impstate->cache);
+ auto_free(device->machine, mips3->impstate->cache);
}
diff --git a/src/emu/cpu/powerpc/ppcdrc.c b/src/emu/cpu/powerpc/ppcdrc.c
index 283b596032e..3c0d830f1d9 100644
--- a/src/emu/cpu/powerpc/ppcdrc.c
+++ b/src/emu/cpu/powerpc/ppcdrc.c
@@ -163,7 +163,7 @@ struct _compiler_state
struct _ppcimp_state
{
/* core state */
- drccache * cache; /* pointer to the DRC code cache */
+ drc_cache * cache; /* pointer to the DRC code cache */
drcuml_state * drcuml; /* DRC UML generator state */
ppc_frontend * drcfe; /* pointer to the DRC front-end state */
UINT32 drcoptions; /* configurable DRC options */
@@ -551,23 +551,21 @@ static void ppcdrc_init(powerpc_flavor flavor, UINT8 cap, int tb_divisor, legacy
powerpc_state *ppc;
drcbe_info beinfo;
UINT32 flags = 0;
- drccache *cache;
+ drc_cache *cache;
int regnum;
/* allocate enough space for the cache and the core */
- cache = drccache_alloc(CACHE_SIZE + sizeof(*ppc));
- if (cache == NULL)
- fatalerror("Unable to allocate cache of size %d", (UINT32)(CACHE_SIZE + sizeof(*ppc)));
+ cache = auto_alloc(device->machine, drc_cache(CACHE_SIZE + sizeof(*ppc)));
/* allocate the core from the near cache */
- *(powerpc_state **)device->token() = ppc = (powerpc_state *)drccache_memory_alloc_near(cache, sizeof(*ppc));
+ *(powerpc_state **)device->token() = ppc = (powerpc_state *)cache->alloc_near(sizeof(*ppc));
memset(ppc, 0, sizeof(*ppc));
/* initialize the core */
ppccom_init(ppc, flavor, cap, tb_divisor, device, irqcallback);
/* allocate the implementation-specific state from the full cache */
- ppc->impstate = (ppcimp_state *)drccache_memory_alloc_near(cache, sizeof(*ppc->impstate));
+ ppc->impstate = (ppcimp_state *)cache->alloc_near(sizeof(*ppc->impstate));
memset(ppc->impstate, 0, sizeof(*ppc->impstate));
ppc->impstate->cache = cache;
@@ -731,7 +729,7 @@ static CPU_EXIT( ppcdrc )
/* clean up the DRC */
auto_free(device->machine, ppc->impstate->drcfe);
drcuml_free(ppc->impstate->drcuml);
- drccache_free(ppc->impstate->cache);
+ auto_free(device->machine, ppc->impstate->cache);
}
diff --git a/src/emu/cpu/rsp/rspdrc.c b/src/emu/cpu/rsp/rspdrc.c
index 662f8adefc4..821d0ca541e 100644
--- a/src/emu/cpu/rsp/rspdrc.c
+++ b/src/emu/cpu/rsp/rspdrc.c
@@ -104,7 +104,7 @@ struct _compiler_state
struct _rspimp_state
{
/* core state */
- drccache * cache; /* pointer to the DRC code cache */
+ drc_cache * cache; /* pointer to the DRC code cache */
drcuml_state * drcuml; /* DRC UML generator state */
rsp_frontend * drcfe; /* pointer to the DRC front-end state */
UINT32 drcoptions; /* configurable DRC options */
@@ -604,26 +604,22 @@ static void rspcom_init(rsp_state *rsp, legacy_cpu_device *device, device_irq_ca
static CPU_INIT( rsp )
{
rsp_state *rsp;
- drccache *cache;
+ drc_cache *cache;
UINT32 flags = 0;
int regnum;
//int elnum;
/* allocate enough space for the cache and the core */
- cache = (drccache *)drccache_alloc(CACHE_SIZE + sizeof(*rsp));
- if (cache == NULL)
- {
- fatalerror("Unable to allocate cache of size %d", (UINT32)(CACHE_SIZE + sizeof(*rsp)));
- }
+ cache = auto_alloc(device->machine, drc_cache(CACHE_SIZE + sizeof(*rsp)));
/* allocate the core memory */
- *(rsp_state **)device->token() = rsp = (rsp_state *)drccache_memory_alloc_near(cache, sizeof(*rsp));
+ *(rsp_state **)device->token() = rsp = (rsp_state *)cache->alloc_near(sizeof(*rsp));
memset(rsp, 0, sizeof(*rsp));
rspcom_init(rsp, device, irqcallback);
/* allocate the implementation-specific state from the full cache */
- rsp->impstate = (rspimp_state *)drccache_memory_alloc_near(cache, sizeof(*rsp->impstate));
+ rsp->impstate = (rspimp_state *)cache->alloc_near(sizeof(*rsp->impstate));
memset(rsp->impstate, 0, sizeof(*rsp->impstate));
rsp->impstate->cache = cache;
@@ -712,7 +708,7 @@ static CPU_EXIT( rsp )
/* clean up the DRC */
auto_free(device->machine, rsp->impstate->drcfe);
drcuml_free(rsp->impstate->drcuml);
- drccache_free(rsp->impstate->cache);
+ auto_free(device->machine, rsp->impstate->cache);
}
diff --git a/src/emu/cpu/sh2/sh2comn.h b/src/emu/cpu/sh2/sh2comn.h
index cf72e90df48..3bd1915f7f5 100644
--- a/src/emu/cpu/sh2/sh2comn.h
+++ b/src/emu/cpu/sh2/sh2comn.h
@@ -154,7 +154,7 @@ typedef struct
void (*ftcsr_read_callback)(UINT32 data);
#ifdef USE_SH2DRC
- drccache * cache; /* pointer to the DRC code cache */
+ drc_cache * cache; /* pointer to the DRC code cache */
drcuml_state * drcuml; /* DRC UML generator state */
sh2_frontend * drcfe; /* pointer to the DRC front-end state */
UINT32 drcoptions; /* configurable DRC options */
diff --git a/src/emu/cpu/sh2/sh2drc.c b/src/emu/cpu/sh2/sh2drc.c
index 30885a1aa41..bc7abd87851 100644
--- a/src/emu/cpu/sh2/sh2drc.c
+++ b/src/emu/cpu/sh2/sh2drc.c
@@ -675,18 +675,16 @@ static void cfunc_SUBV(void *param)
static CPU_INIT( sh2 )
{
sh2_state *sh2 = get_safe_token(device);
- drccache *cache;
+ drc_cache *cache;
drcbe_info beinfo;
UINT32 flags = 0;
int regnum;
/* allocate enough space for the cache and the core */
- cache = drccache_alloc(CACHE_SIZE + sizeof(sh2_state));
- if (cache == NULL)
- fatalerror("Unable to allocate cache of size %d", (UINT32)(CACHE_SIZE + sizeof(sh2_state)));
+ cache = auto_alloc(device->machine, drc_cache(CACHE_SIZE + sizeof(sh2_state)));
/* allocate the core memory */
- *(sh2_state **)device->token() = sh2 = (sh2_state *)drccache_memory_alloc_near(cache, sizeof(sh2_state));
+ *(sh2_state **)device->token() = sh2 = (sh2_state *)cache->alloc_near(sizeof(sh2_state));
memset(sh2, 0, sizeof(sh2_state));
/* initialize the common core parts */
@@ -772,7 +770,7 @@ static CPU_EXIT( sh2 )
/* clean up the DRC */
auto_free(device->machine, sh2->drcfe);
drcuml_free(sh2->drcuml);
- drccache_free(sh2->cache);
+ auto_free(device->machine, sh2->cache);
}