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