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; }
void *drc_alloc(drc_core *drc, size_t amount) { /* if we don't have enough space, reset the cache */ if (drc->cache_top >= drc->cache_danger - amount) drc_cache_reset(drc); /* if we still don't have enough space, fail */ if (drc->cache_top >= drc->cache_danger - amount) return NULL; /* adjust the end and danger values downward */ drc->cache_end -= amount; drc->cache_danger -= amount; return drc->cache_end; }