mirror of
https://github.com/holub/mame
synced 2025-05-18 03:35:03 +03:00
Convert drccache to C++
This commit is contained in:
parent
7c15acffe2
commit
c12dd417cd
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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); }
|
||||
|
||||
// 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);
|
||||
|
||||
/***************************************************************************
|
||||
FUNCTION PROTOTYPES
|
||||
***************************************************************************/
|
||||
private:
|
||||
// largest block of code that can be generated at once
|
||||
static const size_t CODEGEN_MAX_BYTES = 65536;
|
||||
|
||||
/* ----- initialization/teardown ----- */
|
||||
// minimum alignment, in bytes (must be power of 2)
|
||||
static const size_t CACHE_ALIGNMENT = 8;
|
||||
|
||||
/* allocate the cache itself */
|
||||
drccache *drccache_alloc(size_t bytes);
|
||||
// largest permanent allocation we allow
|
||||
static const size_t MAX_PERMANENT_ALLOC = 1024;
|
||||
|
||||
/* free the cache */
|
||||
void drccache_free(drccache *cache);
|
||||
// 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
|
||||
|
||||
/* ----- 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);
|
||||
// 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__ */
|
||||
|
@ -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 *)¶mmem[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));
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user