drc_core *drc_init(UINT8 cpunum, drc_config *config) { int address_bits = config->address_bits; int effective_address_bits = address_bits - config->lsbs_to_ignore; drc_core *drc; /* allocate memory */ drc = malloc(sizeof(*drc)); if (!drc) return NULL; memset(drc, 0, sizeof(*drc)); /* copy in relevant data from the config */ drc->pcptr = config->pcptr; drc->icountptr = config->icountptr; drc->esiptr = config->esiptr; drc->cb_reset = config->cb_reset; drc->cb_recompile = config->cb_recompile; drc->cb_entrygen = config->cb_entrygen; drc->uses_fp = config->uses_fp; drc->uses_sse = config->uses_sse; drc->pc_in_memory = config->pc_in_memory; drc->icount_in_memory = config->icount_in_memory; drc->fpcw_curr = fp_control[0]; drc->mxcsr_curr = sse_control[0]; /* allocate cache */ drc->cache_base = osd_alloc_executable(config->cache_size); if (!drc->cache_base) return NULL; drc->cache_end = drc->cache_base + config->cache_size; drc->cache_danger = drc->cache_end - 65536; /* compute shifts and masks */ drc->l1bits = effective_address_bits/2; drc->l2bits = effective_address_bits - drc->l1bits; drc->l1shift = config->lsbs_to_ignore + drc->l2bits; drc->l2mask = ((1 << drc->l2bits) - 1) << config->lsbs_to_ignore; drc->l2scale = 4 >> config->lsbs_to_ignore; /* allocate lookup tables */ drc->lookup_l1 = malloc(sizeof(*drc->lookup_l1) * (1 << drc->l1bits)); drc->lookup_l2_recompile = malloc(sizeof(*drc->lookup_l2_recompile) * (1 << drc->l2bits)); if (!drc->lookup_l1 || !drc->lookup_l2_recompile) return NULL; memset(drc->lookup_l1, 0, sizeof(*drc->lookup_l1) * (1 << drc->l1bits)); memset(drc->lookup_l2_recompile, 0, sizeof(*drc->lookup_l2_recompile) * (1 << drc->l2bits)); /* allocate the sequence and tentative lists */ drc->sequence_count_max = config->max_instructions; drc->sequence_list = malloc(drc->sequence_count_max * sizeof(*drc->sequence_list)); drc->tentative_count_max = config->max_instructions; drc->tentative_list = malloc(drc->tentative_count_max * sizeof(*drc->tentative_list)); if (!drc->sequence_list || !drc->tentative_list) return NULL; /* seed the cache */ drc_cache_reset(drc); return drc; }
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) { memset(m_free, 0, sizeof(m_free)); memset(m_nearfree, 0, sizeof(m_nearfree)); }
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; }