--- upstream/dynamips-0.2.6-RC5/insn_lookup.c 2007/10/06 16:09:07 6 +++ trunk/insn_lookup.c 2007/10/06 16:45:40 12 @@ -1,5 +1,5 @@ /* - * Cisco 7200 (Predator) simulation platform. + * Cisco router simulation platform. * Copyright (c) 2006 Christophe Fillot (cf@utc.fr) * * Instruction Lookup Tables. @@ -17,6 +17,7 @@ #include "utils.h" #include "hash.h" #include "insn_lookup.h" +#include "dynamips.h" /* Hash function for a CBM */ static inline u_int cbm_hash_f(void *ccbm) @@ -313,12 +314,190 @@ ilt_postprocessing(ilt); } +/* Dump an instruction lookup table */ +static int ilt_dump(char *table_name,insn_lookup_t *ilt) +{ + rfc_array_t *rfct; + char *filename; + FILE *fd; + int i,j; + + filename = dyn_sprintf("ilt_dump_%s_%s.txt",sw_version_tag,table_name); + assert(filename != NULL); + + fd = fopen(filename,"w"); + assert(fd != NULL); + + fprintf(fd,"ILT %p: nr_insn=%d, cbm_size=%d\n", + ilt,ilt->nr_insn,ilt->cbm_size); + + for(i=0;irfct[i]; + + fprintf(fd,"RFCT %d: nr_elements=%d, nr_eqid=%d\n", + i,rfct->nr_elements,rfct->nr_eqid); + + for(j=0;jnr_elements;j++) + fprintf(fd," (0x%4.4x,0x%4.4x) = 0x%4.4x\n",i,j,rfct->eqID[j]); + } + + fclose(fd); + return(0); +} + +/* Write the specified RFC array to disk */ +static void ilt_store_rfct(FILE *fd,int id,rfc_array_t *rfct) +{ + /* Store RFC array ID + number of elements */ + fwrite(&id,sizeof(id),1,fd); + fwrite(&rfct->nr_elements,sizeof(rfct->nr_elements),1,fd); + fwrite(&rfct->nr_eqid,sizeof(rfct->nr_eqid),1,fd); + + fwrite(rfct->eqID,sizeof(int),rfct->nr_elements,fd); +} + +/* Write the full instruction lookup table */ +static void ilt_store_table(FILE *fd,insn_lookup_t *ilt) +{ + int i; + + for(i=0;irfct[i] != NULL) + ilt_store_rfct(fd,i,ilt->rfct[i]); +} + +/* Load an RFC array from disk */ +static int ilt_load_rfct(FILE *fd,insn_lookup_t *ilt) +{ + u_int id,nr_elements,nr_eqid; + rfc_array_t *rfct; + size_t len; + + /* Read ID and number of elements */ + if ((fread(&id,sizeof(id),1,fd) != 1) || + (fread(&nr_elements,sizeof(nr_elements),1,fd) != 1) || + (fread(&nr_eqid,sizeof(nr_eqid),1,fd) != 1)) + return(-1); + + if ((id >= RFC_ARRAY_NUMBER) || (nr_elements > RFC_ARRAY_MAXSIZE)) + return(-1); + + /* Allocate the RFC array with the eqID table */ + len = sizeof(*rfct) + (nr_elements * sizeof(int)); + + if (!(rfct = malloc(len))) + return(-1); + + memset(rfct,0,sizeof(*rfct)); + rfct->nr_elements = nr_elements; + rfct->nr_eqid = nr_eqid; + + /* Read the equivalent ID array */ + if (fread(rfct->eqID,sizeof(int),nr_elements,fd) != nr_elements) { + free(rfct); + return(-1); + } + + ilt->rfct[id] = rfct; + return(0); +} + +/* Check an instruction table loaded from disk */ +static int ilt_check_cached_table(insn_lookup_t *ilt) +{ + int i; + + /* All arrays must have been loaded */ + for(i=0;irfct[i]) + return(-1); + + return(0); +} + +/* Load a full instruction table from disk */ +static insn_lookup_t *ilt_load_table(FILE *fd) +{ + insn_lookup_t *ilt; + int i; + + if (!(ilt = malloc(sizeof(*ilt)))) + return NULL; + + memset(ilt,0,sizeof(*ilt)); + fseek(fd,0,SEEK_SET); + + for(i=0;ichk_lo = chk_lo; ilt->chk_hi = chk_hi; + /* Compile the instruction opcodes */ ilt_compile(ilt); + + /* Store the result on disk for future exec */ + ilt_cache_store(table_name,ilt); return(ilt); }