# HG changeset patch # User nkeynes # Date 1191064000 0 # Node ID 5f8413358e7f908686beab8faad251bc84fef84c # Parent 549e0083544896e4ef7a95aca04def3394b9bf1c Change extend-block to take a requested size Terminate blocks on page boundaries for easier invalidation --- a/src/sh4/sh4trans.c Sat Sep 29 05:33:02 2007 +0000 +++ b/src/sh4/sh4trans.c Sat Sep 29 11:06:40 2007 +0000 @@ -1,5 +1,5 @@ /** - * $Id: sh4trans.c,v 1.5 2007-09-28 07:27:20 nkeynes Exp $ + * $Id: sh4trans.c,v 1.6 2007-09-29 11:06:40 nkeynes Exp $ * * SH4 translation core module. This part handles the non-target-specific * section of the translation. @@ -86,6 +86,7 @@ void * sh4_translate_basic_block( sh4addr_t start ) { sh4addr_t pc = start; + sh4addr_t lastpc = (pc&0xFFFFF000)+0x1000; int done; xlat_cache_block_t block = xlat_start_block( start ); xlat_output = (uint8_t *)block->code; @@ -95,14 +96,23 @@ do { if( eob - xlat_output < MAX_INSTRUCTION_SIZE ) { uint8_t *oldstart = block->code; - block = xlat_extend_block(); + block = xlat_extend_block( xlat_output - oldstart + MAX_INSTRUCTION_SIZE ); xlat_output = block->code + (xlat_output - oldstart); eob = block->code + block->size; } done = sh4_x86_translate_instruction( pc ); + assert( xlat_output <= eob ); pc += 2; + if ( pc >= lastpc ) { + done = 2; + } } while( !done ); pc += (done - 2); + if( eob - xlat_output < EPILOGUE_SIZE ) { + uint8_t *oldstart = block->code; + block = xlat_extend_block( xlat_output - oldstart + EPILOGUE_SIZE ); + xlat_output = block->code + (xlat_output - oldstart); + } sh4_translate_end_block(pc); xlat_commit_block( xlat_output - block->code, pc-start ); return block->code; --- a/src/sh4/sh4trans.h Sat Sep 29 05:33:02 2007 +0000 +++ b/src/sh4/sh4trans.h Sat Sep 29 11:06:40 2007 +0000 @@ -1,5 +1,5 @@ /** - * $Id: sh4trans.h,v 1.3 2007-09-28 07:27:20 nkeynes Exp $ + * $Id: sh4trans.h,v 1.4 2007-09-29 11:06:40 nkeynes Exp $ * * SH4->x86 translation module * @@ -23,7 +23,10 @@ * writing the entire epilogue */ #define MAX_INSTRUCTION_SIZE 256 - +/** Maximum size of the translation epilogue (current real size is 116 bytes, so + * allows a little room + */ +#define EPILOGUE_SIZE 128 /** */ --- a/src/sh4/xltcache.c Sat Sep 29 05:33:02 2007 +0000 +++ b/src/sh4/xltcache.c Sat Sep 29 11:06:40 2007 +0000 @@ -1,5 +1,5 @@ /** - * $Id: xltcache.c,v 1.6 2007-09-28 07:26:35 nkeynes Exp $ + * $Id: xltcache.c,v 1.7 2007-09-29 11:06:40 nkeynes Exp $ * * Translation cache management. This part is architecture independent. * @@ -53,7 +53,6 @@ xlat_cache_block_t xlat_old_cache; xlat_cache_block_t xlat_old_cache_ptr; static void ***xlat_lut; -static void **xlat_lut2; /* second-tier page info */ static gboolean xlat_initialized = FALSE; void xlat_cache_init() @@ -197,10 +196,10 @@ void *xlat_get_code( sh4addr_t address ) { - void *result; + void *result = NULL; void **page = xlat_lut[XLAT_LUT_PAGE(address)]; if( page != NULL ) { - result = (void *)(((uint32_t)page[XLAT_LUT_ENTRY(address)]) & 0xFFFFFFFC); + result = (void *)(((uint32_t)(page[XLAT_LUT_ENTRY(address)])) & 0xFFFFFFFC); } return result; } @@ -237,6 +236,7 @@ static inline xlat_cache_block_t xlat_cut_block( xlat_cache_block_t block, int cutsize ) { cutsize = (cutsize + 3) & 0xFFFFFFFC; // force word alignment + assert( cutsize <= block->size ); if( block->size > cutsize + MIN_TOTAL_SIZE ) { int oldsize = block->size; block->size = cutsize; @@ -365,36 +365,38 @@ return xlat_new_create_ptr; } -xlat_cache_block_t xlat_extend_block() +xlat_cache_block_t xlat_extend_block( uint32_t newSize ) { - if( xlat_new_cache_ptr->size == 0 ) { - /* Migrate to the front of the cache to keep it contiguous */ - xlat_new_create_ptr->active = 0; - char *olddata = xlat_new_create_ptr->code; - int oldsize = xlat_new_create_ptr->size; - int size = oldsize + MIN_BLOCK_SIZE; /* minimum expansion */ - void **lut_entry = xlat_new_create_ptr->lut_entry; - int allocation = -sizeof(struct xlat_cache_block); - xlat_new_cache_ptr = xlat_new_cache; - do { + while( xlat_new_create_ptr->size < newSize ) { + if( xlat_new_cache_ptr->size == 0 ) { + /* Migrate to the front of the cache to keep it contiguous */ + xlat_new_create_ptr->active = 0; + char *olddata = xlat_new_create_ptr->code; + int oldsize = xlat_new_create_ptr->size; + int size = oldsize + MIN_BLOCK_SIZE; /* minimum expansion */ + void **lut_entry = xlat_new_create_ptr->lut_entry; + int allocation = -sizeof(struct xlat_cache_block); + xlat_new_cache_ptr = xlat_new_cache; + do { + if( xlat_new_cache_ptr->active ) { + xlat_promote_to_temp_space( xlat_new_cache_ptr ); + } + allocation += xlat_new_cache_ptr->size + sizeof(struct xlat_cache_block); + xlat_new_cache_ptr = NEXT(xlat_new_cache_ptr); + } while( allocation < size ); + xlat_new_create_ptr = xlat_new_cache; + xlat_new_create_ptr->active = 1; + xlat_new_create_ptr->size = allocation; + xlat_new_create_ptr->lut_entry = lut_entry; + *lut_entry = &xlat_new_create_ptr->code; + memmove( xlat_new_create_ptr->code, olddata, oldsize ); + } else { if( xlat_new_cache_ptr->active ) { xlat_promote_to_temp_space( xlat_new_cache_ptr ); } - allocation += xlat_new_cache_ptr->size + sizeof(struct xlat_cache_block); + xlat_new_create_ptr->size += xlat_new_cache_ptr->size + sizeof(struct xlat_cache_block); xlat_new_cache_ptr = NEXT(xlat_new_cache_ptr); - } while( allocation < size ); - xlat_new_create_ptr = xlat_new_cache; - xlat_new_create_ptr->active = 1; - xlat_new_create_ptr->size = allocation; - xlat_new_create_ptr->lut_entry = lut_entry; - *lut_entry = &xlat_new_create_ptr->code; - memmove( xlat_new_create_ptr->code, olddata, oldsize ); - } else { - if( xlat_new_cache_ptr->active ) { - xlat_promote_to_temp_space( xlat_new_cache_ptr ); } - xlat_new_create_ptr->size += xlat_new_cache_ptr->size + sizeof(struct xlat_cache_block); - xlat_new_cache_ptr = NEXT(xlat_new_cache_ptr); } return xlat_new_create_ptr; --- a/src/sh4/xltcache.h Sat Sep 29 05:33:02 2007 +0000 +++ b/src/sh4/xltcache.h Sat Sep 29 11:06:40 2007 +0000 @@ -1,5 +1,5 @@ /** - * $Id: xltcache.h,v 1.5 2007-09-28 07:26:35 nkeynes Exp $ + * $Id: xltcache.h,v 1.6 2007-09-29 11:06:40 nkeynes Exp $ * * Translation cache support (architecture independent) * @@ -37,7 +37,7 @@ * and xlat_commit_block()). * @return the new block, which may be different from the old block. */ -xlat_cache_block_t xlat_extend_block(); +xlat_cache_block_t xlat_extend_block( uint32_t newSize ); /** * Commit the current translation block