revision 1149:da6124fceec6
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 1149:da6124fceec6 |
parent | 1148:8e75fab17be8 |
child | 1150:1038800cecd8 |
author | nkeynes |
date | Wed Nov 10 08:37:42 2010 +1000 (13 years ago) |
Add chain pointer to the xlat cache, so that we can maintain multiple blocks
for the same address. This prevents thrashing in cases where we would other
keep retranslating the same blocks over and over again due to varying
xlat_sh4_mode values
for the same address. This prevents thrashing in cases where we would other
keep retranslating the same blocks over and over again due to varying
xlat_sh4_mode values
src/sh4/sh4trans.c | view | annotate | diff | log | ||
src/sh4/sh4x86.in | view | annotate | diff | log | ||
src/xlat/xltcache.c | view | annotate | diff | log | ||
src/xlat/xltcache.h | view | annotate | diff | log |
1.1 --- a/src/sh4/sh4trans.c Wed Nov 10 08:23:05 2010 +10001.2 +++ b/src/sh4/sh4trans.c Wed Nov 10 08:37:42 2010 +10001.3 @@ -58,7 +58,15 @@1.4 }1.6 code = xlat_get_code_by_vma( sh4r.pc );1.7 - if( code == NULL || sh4r.xlat_sh4_mode != XLAT_BLOCK_MODE(code) ) {1.8 + if( code != NULL ) {1.9 + while( sh4r.xlat_sh4_mode != XLAT_BLOCK_MODE(code) ) {1.10 + code = XLAT_BLOCK_CHAIN(code);1.11 + if( code == NULL ) {1.12 + code = sh4_translate_basic_block( sh4r.pc );1.13 + break;1.14 + }1.15 + }1.16 + } else {1.17 code = sh4_translate_basic_block( sh4r.pc );1.18 }1.19 code();
2.1 --- a/src/sh4/sh4x86.in Wed Nov 10 08:23:05 2010 +10002.2 +++ b/src/sh4/sh4x86.in Wed Nov 10 08:37:42 2010 +10002.3 @@ -521,6 +521,7 @@2.5 /** Offset of xlat_sh4_mode field relative to the code pointer */2.6 #define XLAT_SH4_MODE_CODE_OFFSET (uint32_t)(offsetof(struct xlat_cache_block, xlat_sh4_mode) - offsetof(struct xlat_cache_block,code) )2.7 +#define XLAT_CHAIN_CODE_OFFSET (uint32_t)(offsetof(struct xlat_cache_block, chain) - offsetof(struct xlat_cache_block,code) )2.9 /**2.10 * Test if the loaded target code pointer in %eax is valid, and if so jump2.11 @@ -528,6 +529,7 @@2.12 */2.13 static void jump_next_block()2.14 {2.15 + uint8_t *ptr = xlat_output;2.16 TESTP_rptr_rptr(REG_EAX, REG_EAX);2.17 JE_label(nocode);2.18 if( sh4_x86.sh4_mode == SH4_MODE_UNKNOWN ) {2.19 @@ -549,7 +551,11 @@2.20 } else {2.21 JMP_rptr(REG_EAX);2.22 }2.23 - JMP_TARGET(nocode); JMP_TARGET(wrongmode);2.24 + JMP_TARGET(wrongmode);2.25 + MOVL_r32disp_r32( REG_EAX, XLAT_CHAIN_CODE_OFFSET, REG_EAX );2.26 + int rel = ptr - xlat_output;2.27 + JMP_prerel(rel);2.28 + JMP_TARGET(nocode);2.29 }2.31 static void exit_block()
3.1 --- a/src/xlat/xltcache.c Wed Nov 10 08:23:05 2010 +10003.2 +++ b/src/xlat/xltcache.c Wed Nov 10 08:37:42 2010 +10003.3 @@ -124,7 +124,12 @@3.4 int i;3.5 for( i=0; i<XLAT_LUT_PAGE_ENTRIES; i++ ) {3.6 if( IS_ENTRY_POINT(page[i]) ) {3.7 - XLAT_BLOCK_FOR_CODE(page[i])->active = 0;3.8 + void *p = page[i];3.9 + do {3.10 + xlat_cache_block_t block = XLAT_BLOCK_FOR_CODE(p);3.11 + block->active = 0;3.12 + p = block->chain;3.13 + } while( p != NULL );3.14 }3.15 page[i] = NULL;3.16 }3.17 @@ -306,6 +311,7 @@3.18 start_block->active = 1;3.19 start_block->size = allocation;3.20 start_block->lut_entry = block->lut_entry;3.21 + start_block->chain = block->chain;3.22 start_block->fpscr_mask = block->fpscr_mask;3.23 start_block->fpscr = block->fpscr;3.24 start_block->recover_table_offset = block->recover_table_offset;3.25 @@ -353,6 +359,7 @@3.26 start_block->active = 1;3.27 start_block->size = allocation;3.28 start_block->lut_entry = block->lut_entry;3.29 + start_block->chain = block->chain;3.30 start_block->fpscr_mask = block->fpscr_mask;3.31 start_block->fpscr = block->fpscr;3.32 start_block->recover_table_offset = block->recover_table_offset;3.33 @@ -398,8 +405,12 @@3.34 }3.36 if( IS_ENTRY_POINT(xlat_lut[XLAT_LUT_PAGE(address)][XLAT_LUT_ENTRY(address)]) ) {3.37 - xlat_cache_block_t oldblock = XLAT_BLOCK_FOR_CODE(xlat_lut[XLAT_LUT_PAGE(address)][XLAT_LUT_ENTRY(address)]);3.38 - oldblock->active = 0;3.39 + void *p = xlat_lut[XLAT_LUT_PAGE(address)][XLAT_LUT_ENTRY(address)];3.40 + xlat_cache_block_t oldblock = XLAT_BLOCK_FOR_CODE(p);3.41 + assert( oldblock->active );3.42 + xlat_new_create_ptr->chain = p;3.43 + } else {3.44 + xlat_new_create_ptr->chain = NULL;3.45 }3.47 xlat_lut[XLAT_LUT_PAGE(address)][XLAT_LUT_ENTRY(address)] =3.48 @@ -419,6 +430,7 @@3.49 int oldsize = xlat_new_create_ptr->size;3.50 int size = oldsize + MIN_BLOCK_SIZE; /* minimum expansion */3.51 void **lut_entry = xlat_new_create_ptr->lut_entry;3.52 + void *chain = xlat_new_create_ptr->chain;3.53 int allocation = (int)-sizeof(struct xlat_cache_block);3.54 xlat_new_cache_ptr = xlat_new_cache;3.55 do {3.56 @@ -432,6 +444,7 @@3.57 xlat_new_create_ptr->active = 1;3.58 xlat_new_create_ptr->size = allocation;3.59 xlat_new_create_ptr->lut_entry = lut_entry;3.60 + xlat_new_create_ptr->chain = chain;3.61 *lut_entry = &xlat_new_create_ptr->code;3.62 memmove( xlat_new_create_ptr->code, olddata, oldsize );3.63 } else {
4.1 --- a/src/xlat/xltcache.h Wed Nov 10 08:23:05 2010 +10004.2 +++ b/src/xlat/xltcache.h Wed Nov 10 08:37:42 2010 +10004.3 @@ -41,6 +41,7 @@4.4 int active; /* 0 = deleted, 1 = normal. 2 = accessed (temp-space only) */4.5 uint32_t size;4.6 void **lut_entry; /* For deletion */4.7 + void *chain;4.8 uint32_t xlat_sh4_mode; /* comparison with sh4r.xlat_sh4_mode */4.9 uint32_t recover_table_offset; // Offset from code[0] of the recovery table;4.10 uint32_t recover_table_size;4.11 @@ -52,6 +53,7 @@4.12 #define XLAT_BLOCK_FOR_CODE(code) (((xlat_cache_block_t)code)-1)4.14 #define XLAT_BLOCK_MODE(code) (XLAT_BLOCK_FOR_CODE(code)->xlat_sh4_mode)4.15 +#define XLAT_BLOCK_CHAIN(code) (XLAT_BLOCK_FOR_CODE(code)->chain)4.16 #define XLAT_RECOVERY_TABLE(code) ((xlat_recovery_record_t)(((char *)code) + XLAT_BLOCK_FOR_CODE(code)->recover_table_offset))4.18 /**4.19 @@ -74,7 +76,6 @@4.21 /**4.22 * Commit the current translation block4.23 - * @param addr target address (for the lookup table)4.24 * @param destsize final size of the translation in bytes.4.25 * @param srcsize size of the original data that was translated in bytes4.26 */
.