Search
lxdream.org :: lxdream/src/xlat/xltcache.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/xlat/xltcache.c
changeset 1182:b38a327ad8fa
prev1175:712c418cad83
next1186:2dc47c67bb93
author nkeynes
date Sun Nov 27 18:20:21 2011 +1000 (10 years ago)
permissions -rw-r--r--
last change Add block profiling option to count the number of executions of each block,
and dump them out from most-to-least used.
file annotate diff log raw
1.1 --- a/src/xlat/xltcache.c Wed May 11 20:25:49 2011 +1000
1.2 +++ b/src/xlat/xltcache.c Sun Nov 27 18:20:21 2011 +1000
1.3 @@ -37,6 +37,8 @@
1.4 #define XLAT_LUT_ENTRY_EMPTY (void *)0
1.5 #define XLAT_LUT_ENTRY_USED (void *)1
1.6
1.7 +#define XLAT_ADDR_FROM_ENTRY(pagenum,entrynum) ((((pagenum)&0xFFFF)<<13)|(((entrynum)<<1)&0x1FFE))
1.8 +
1.9 #define NEXT(block) ( (xlat_cache_block_t)&((block)->code[(block)->size]))
1.10 #define IS_ENTRY_POINT(ent) (ent > XLAT_LUT_ENTRY_USED)
1.11 #define IS_ENTRY_USED(ent) (ent != XLAT_LUT_ENTRY_EMPTY)
1.12 @@ -575,3 +577,92 @@
1.13 #endif
1.14 }
1.15
1.16 +typedef struct {
1.17 + xlat_cache_block_t block;
1.18 + sh4addr_t sh4_pc;
1.19 +} block_sh4_entry;
1.20 +
1.21 +unsigned int xlat_get_active_block_count()
1.22 +{
1.23 + unsigned int count = 0;
1.24 + xlat_cache_block_t ptr = xlat_new_cache;
1.25 + while( ptr->size != 0 ) {
1.26 + if( ptr->active != 0 ) {
1.27 + count++;
1.28 + }
1.29 + ptr = NEXT(ptr);
1.30 + }
1.31 + return count;
1.32 +}
1.33 +
1.34 +unsigned int xlat_get_active_blocks( block_sh4_entry *blocks, unsigned int size )
1.35 +{
1.36 + unsigned int count = 0;
1.37 + xlat_cache_block_t ptr = xlat_new_cache;
1.38 + while( ptr->size != 0 ) {
1.39 + if( ptr->active != 0 ) {
1.40 + blocks[count].block = ptr;
1.41 + blocks[count].sh4_pc = 0;
1.42 + count++;
1.43 + }
1.44 + if( count >= size )
1.45 + break;
1.46 + ptr = NEXT(ptr);
1.47 + }
1.48 + return count;
1.49 +}
1.50 +
1.51 +void xlat_get_block_sh4addrs( block_sh4_entry *blocks, unsigned int size )
1.52 +{
1.53 + unsigned i;
1.54 + for( i=0; i<XLAT_LUT_PAGES;i ++ ) {
1.55 + void **page = xlat_lut[i];
1.56 + if( page != NULL ) {
1.57 + for( unsigned j=0; j < XLAT_LUT_PAGE_ENTRIES; j++ ) {
1.58 + void *code = (void *)(((uintptr_t)(page[j])) & (~((uintptr_t)0x03)));
1.59 + if( code != NULL ) {
1.60 + xlat_cache_block_t ptr = XLAT_BLOCK_FOR_CODE(code);
1.61 + sh4addr_t pc = XLAT_ADDR_FROM_ENTRY(i,j);
1.62 + for( unsigned k=0; k<size; k++ ) {
1.63 + if( blocks[k].block == ptr ) {
1.64 + blocks[k].sh4_pc = pc;
1.65 + ptr = ptr->chain;
1.66 + if( ptr == NULL )
1.67 + break;
1.68 + else {
1.69 + ptr = XLAT_BLOCK_FOR_CODE(ptr);
1.70 + k = 0;
1.71 + }
1.72 + }
1.73 + }
1.74 + }
1.75 + }
1.76 + }
1.77 + }
1.78 +}
1.79 +
1.80 +static int xlat_compare_active_field( const void *a, const void *b )
1.81 +{
1.82 + const block_sh4_entry *ptra = (const block_sh4_entry *)a;
1.83 + const block_sh4_entry *ptrb = (const block_sh4_entry *)b;
1.84 + return ptrb->block->active - ptra->block->active;
1.85 +}
1.86 +
1.87 +void xlat_dump_cache_by_activity( unsigned int topN )
1.88 +{
1.89 + int i=0;
1.90 + int count = xlat_get_active_block_count();
1.91 +
1.92 + block_sh4_entry blocks[count];
1.93 + xlat_get_active_blocks(blocks, count);
1.94 + xlat_get_block_sh4addrs(blocks,count);
1.95 + qsort(blocks, count, sizeof(block_sh4_entry), xlat_compare_active_field);
1.96 +
1.97 + if( topN == 0 || topN > count )
1.98 + topN = count;
1.99 + for( unsigned int i=0; i<topN; i++ ) {
1.100 + fprintf(stderr, "0x%08X (%p): %d\n", blocks[i].sh4_pc, blocks[i].block->code, blocks[i].block->active);
1.101 + sh4_translate_disasm_block( stderr, blocks[i].block->code, blocks[i].sh4_pc, NULL );
1.102 + fprintf(stderr, "\n");
1.103 + }
1.104 +}
.