Convert drccache to C++

This commit is contained in:
Aaron Giles 2011-01-05 16:33:00 +00:00
parent 7c15acffe2
commit c12dd417cd
14 changed files with 363 additions and 474 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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
***************************************************************************/
//**************************************************************************
// MACROS
//**************************************************************************
/* 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
***************************************************************************/
/* 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
***************************************************************************/
//**************************************************************************
// DRC CACHE
//**************************************************************************
/* out-of-bounds codegen handlers */
typedef struct _oob_handler oob_handler;
struct _oob_handler
//-------------------------------------------------
// drc_cache - constructor
//-------------------------------------------------
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)
{
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;
memset(m_free, 0, sizeof(m_free));
memset(m_nearfree, 0, sizeof(m_nearfree));
}
/*-------------------------------------------------
drccache_free - free the cache
-------------------------------------------------*/
//-------------------------------------------------
// ~drc_cache - destructor
//-------------------------------------------------
void drccache_free(drccache *cache)
drc_cache::~drc_cache()
{
/* release the memory; this includes the cache object itself */
osd_free_executable(cache->near, cache->size);
// release the memory
osd_free_executable(m_near, m_size);
}
/***************************************************************************
CACHE INFORMATION
***************************************************************************/
//-------------------------------------------------
// flush - flush the cache contents
//-------------------------------------------------
/*-------------------------------------------------
drccache_contains_pointer - return true if a
pointer is within the cache
-------------------------------------------------*/
int drccache_contains_pointer(drccache *cache, const void *ptr)
void drc_cache::flush()
{
return ((const drccodeptr)ptr >= cache->near && (const drccodeptr)ptr < cache->near + cache->size);
// can't flush in the middle of codegen
assert(m_codegen == NULL);
// just reset the top back to the base and re-seed
m_top = m_base;
}
/*-------------------------------------------------
drccache_contains_near_pointer - return true
if a pointer is within the cache
-------------------------------------------------*/
//-------------------------------------------------
// alloc - allocate permanent memory from the
// cache
//-------------------------------------------------
int drccache_contains_near_pointer(drccache *cache, const void *ptr)
void *drc_cache::alloc(size_t bytes)
{
return ((const drccodeptr)ptr >= cache->near && (const drccodeptr)ptr < cache->neartop);
}
/*-------------------------------------------------
drccache_near - return a pointer to the near
part of the cache
-------------------------------------------------*/
drccodeptr drccache_near(drccache *cache)
{
return cache->near;
}
/*-------------------------------------------------
drccache_base - return a pointer to the base
of the cache
-------------------------------------------------*/
drccodeptr drccache_base(drccache *cache)
{
return cache->base;
}
/*-------------------------------------------------
drccache_top - return the current top of the
cache
-------------------------------------------------*/
drccodeptr drccache_top(drccache *cache)
{
return cache->top;
}
/***************************************************************************
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;
}
/*-------------------------------------------------
drccache_memory_alloc - allocate permanent
memory from the cache
-------------------------------------------------*/
void *drccache_memory_alloc(drccache *cache, 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);
// if no space, we just fail
drccodeptr ptr = m_top;
if (ptr + bytes >= m_end)
return NULL;
// otherwise, update the cache top
m_top = (drccodeptr)ALIGN_PTR_UP(ptr + bytes);
return ptr;
}
//-------------------------------------------------
// free - release permanent memory allocated from
// the cache
//-------------------------------------------------
void drc_cache::dealloc(void *memory, size_t bytes)
{
assert(bytes < MAX_PERMANENT_ALLOC);
assert(((drccodeptr)memory >= cache->near && (drccodeptr)memory < cache->base) || ((drccodeptr)memory >= cache->end && (drccodeptr)memory < cache->near + cache->size));
assert(((drccodeptr)memory >= m_near && (drccodeptr)memory < m_base) || ((drccodeptr)memory >= m_end && (drccodeptr)memory < m_near + m_size));
/* determine which free list to add to */
if ((drccodeptr)memory < cache->base)
linkptr = &cache->nearfree[(bytes + CACHE_ALIGNMENT - 1) / CACHE_ALIGNMENT];
// 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 = &cache->free[(bytes + CACHE_ALIGNMENT - 1) / CACHE_ALIGNMENT];
linkptr = &m_free[(bytes + CACHE_ALIGNMENT - 1) / CACHE_ALIGNMENT];
/* link is into the free list for our size */
link->next = *linkptr;
// link is into the free list for our size
free_link *link = (free_link *)memory;
link->m_next = *linkptr;
*linkptr = link;
}
/*-------------------------------------------------
drccache_memory_alloc_temporary - allocate
temporary memory from the cache
-------------------------------------------------*/
//-------------------------------------------------
// begin_codegen - begin code generation
//-------------------------------------------------
void *drccache_memory_alloc_temporary(drccache *cache, size_t 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 allocate in the middle of codegen */
assert(cache->codegen == NULL);
/* if no space, we just fail */
if (ptr + bytes >= cache->end)
// if still no space, we just fail
drccodeptr ptr = m_top;
if (ptr + reserve_bytes >= m_end)
return NULL;
/* otherwise, update the cache top */
cache->top = (drccodeptr)ALIGN_PTR_UP(ptr + bytes);
return ptr;
// otherwise, return a pointer to the cache top
m_codegen = m_top;
return &m_top;
}
//-------------------------------------------------
// end_codegen - complete code generation
//-------------------------------------------------
/***************************************************************************
CODE GENERATION
***************************************************************************/
/*-------------------------------------------------
drccache_begin_codegen - begin code
generation
-------------------------------------------------*/
drccodeptr *drccache_begin_codegen(drccache *cache, UINT32 reserve_bytes)
drccodeptr drc_cache::end_codegen()
{
drccodeptr ptr = cache->top;
drccodeptr result = m_codegen;
/* 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)
return NULL;
/* otherwise, return a pointer to the cache top */
cache->codegen = cache->top;
cache->oobtail = &cache->ooblist;
return &cache->top;
}
/*-------------------------------------------------
drccache_end_codegen - complete code
generation
-------------------------------------------------*/
drccodeptr drccache_end_codegen(drccache *cache)
{
drccodeptr result = cache->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->m_callback)(&m_top, oob->m_param1, oob->m_param2, oob->m_param3);
assert(m_top - m_codegen < CODEGEN_MAX_BYTES);
/* call the callback */
(*oob->callback)(&cache->top, oob->param1, oob->param2, oob->param3);
assert(cache->top - cache->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(m_codegen != NULL);
assert(cache->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);
}

View File

@ -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;
// drc_cache
class drc_cache
{
public:
// out of band codegen callback
typedef void (*oob_func)(drccodeptr *codeptr, void *param1, void *param2, void *param3);
/* out of band codegen callback */
typedef void (*drccache_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); }
/***************************************************************************
FUNCTION PROTOTYPES
***************************************************************************/
// 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);
/* ----- initialization/teardown ----- */
// 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);
/* allocate the cache itself */
drccache *drccache_alloc(size_t bytes);
private:
// largest block of code that can be generated at once
static const size_t CODEGEN_MAX_BYTES = 65536;
/* free the cache */
void drccache_free(drccache *cache);
// 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;
/* ----- cache information ----- */
// 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
/* return true if a pointer is within the cache */
int drccache_contains_pointer(drccache *cache, const void *ptr);
// oob management
struct oob_handler
{
oob_handler *next() const { return m_next; }
/* return true if a pointer is within the near area of the cache */
int drccache_contains_near_pointer(drccache *cache, const void *ptr);
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
/* 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);
// 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__ */

View File

@ -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));
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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 */

View File

@ -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);
}