Search
lxdream.org :: lxdream :: r1149:da6124fceec6
lxdream 0.9.1
released Jun 29
Download Now
changeset1149:da6124fceec6
parent1148:8e75fab17be8
child1150:1038800cecd8
authornkeynes
dateWed 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
src/sh4/sh4trans.c
src/sh4/sh4x86.in
src/xlat/xltcache.c
src/xlat/xltcache.h
1.1 --- a/src/sh4/sh4trans.c Wed Nov 10 08:23:05 2010 +1000
1.2 +++ b/src/sh4/sh4trans.c Wed Nov 10 08:37:42 2010 +1000
1.3 @@ -58,7 +58,15 @@
1.4 }
1.5
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 +1000
2.2 +++ b/src/sh4/sh4x86.in Wed Nov 10 08:37:42 2010 +1000
2.3 @@ -521,6 +521,7 @@
2.4
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.8
2.9 /**
2.10 * Test if the loaded target code pointer in %eax is valid, and if so jump
2.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.30
2.31 static void exit_block()
3.1 --- a/src/xlat/xltcache.c Wed Nov 10 08:23:05 2010 +1000
3.2 +++ b/src/xlat/xltcache.c Wed Nov 10 08:37:42 2010 +1000
3.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.35
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.46
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 +1000
4.2 +++ b/src/xlat/xltcache.h Wed Nov 10 08:37:42 2010 +1000
4.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.13
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.17
4.18 /**
4.19 @@ -74,7 +76,6 @@
4.20
4.21 /**
4.22 * Commit the current translation block
4.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 bytes
4.26 */
.