From 3f012afcda9555d3778fcaade12f6af3948fc6c5 Mon Sep 17 00:00:00 2001 From: David Guillen Fandos Date: Sat, 30 Oct 2021 22:54:51 +0200 Subject: [PATCH] Make ROM hash table mechanism 64 bit compatible. --- arm/arm_emit.h | 2 +- cpu.h | 2 +- cpu_threaded.c | 51 +++++++++++++++++++++++++++++++++---------------- gpsp_config.h | 3 ++- psp/mips_emit.h | 2 +- x86/x86_emit.h | 2 +- 6 files changed, 41 insertions(+), 21 deletions(-) diff --git a/arm/arm_emit.h b/arm/arm_emit.h index 8116d1f..5645534 100644 --- a/arm/arm_emit.h +++ b/arm/arm_emit.h @@ -1973,7 +1973,7 @@ void init_emitter(void) { // Generate handler table memcpy(ldst_lookup_tables, ldst_handler_functions, sizeof(ldst_lookup_tables)); - rom_cache_watermark = 0; + rom_cache_watermark = INITIAL_ROM_WATERMARK; u8 *translation_ptr = (u8*)&rom_translation_cache[0]; // Generate ARMv5+ division code, uses a mix of libgcc and some open bioses. diff --git a/cpu.h b/cpu.h index f411e08..0a34f45 100644 --- a/cpu.h +++ b/cpu.h @@ -156,7 +156,7 @@ extern u32 iwram_stack_optimize; extern u32 translation_gate_targets; extern u32 translation_gate_target_pc[MAX_TRANSLATION_GATES]; -extern u32 *rom_branch_hash[ROM_BRANCH_HASH_SIZE]; +extern u32 rom_branch_hash[ROM_BRANCH_HASH_SIZE]; void flush_translation_cache_rom(void); void flush_translation_cache_ram(void); diff --git a/cpu_threaded.c b/cpu_threaded.c index 77a8cbe..bf4aa4e 100644 --- a/cpu_threaded.c +++ b/cpu_threaded.c @@ -58,10 +58,24 @@ u32 iwram_code_min = ~0U; u32 iwram_code_max = 0U; u32 ewram_code_min = ~0U; u32 ewram_code_max = 0U; -u32 rom_cache_watermark = 0; + +#define INITIAL_ROM_WATERMARK 16 // To avoid NULL aliasing +u32 rom_cache_watermark = INITIAL_ROM_WATERMARK; u8 *bios_swi_entrypoint = NULL; -u32 *rom_branch_hash[ROM_BRANCH_HASH_SIZE]; + +// Contains an offset table to rom_translation cache area +// It features a chaining linked list for collisions +// The rom area has a small header section that contains: +// - PC value for the entry +// - Offset to the next entry (if any) +typedef struct +{ + u32 pc_value; + u32 next_entry; +} hashhdr_type; + +u32 rom_branch_hash[ROM_BRANCH_HASH_SIZE]; typedef struct { @@ -2621,21 +2635,25 @@ u8 function_cc *block_lookup_address_##type(u32 pc) \ case 0x0: \ case 0x8 ... 0xD: \ { \ - u32 hash_target = ((pc * 2654435761U) >> 16) & \ - (ROM_BRANCH_HASH_SIZE - 1); \ - u32 *block_ptr = rom_branch_hash[hash_target]; \ - u32 **block_ptr_address = rom_branch_hash + hash_target; \ - while(block_ptr) \ + u32 hash_target = ((pc * 2654435761U) >> (32 - ROM_BRANCH_HASH_BITS)) \ + & (ROM_BRANCH_HASH_SIZE - 1); \ + \ + hashhdr_type *bhdr; \ + u32 blk_offset = rom_branch_hash[hash_target]; \ + u32 *blk_offset_addr = &rom_branch_hash[hash_target]; \ + while(blk_offset) \ { \ - if(block_ptr[0] == pc) \ + bhdr = (hashhdr_type*)&rom_translation_cache[blk_offset]; \ + if(bhdr->pc_value == pc) \ { \ - block_address = (u8 *)(block_ptr + 2) + block_prologue_size; \ + block_address = &rom_translation_cache[blk_offset + \ + sizeof(hashhdr_type) + block_prologue_size]; \ break; \ } \ - block_ptr_address = (u32 **)(block_ptr + 1); \ - block_ptr = (u32 *)block_ptr[1]; \ + blk_offset = bhdr->next_entry; \ + blk_offset_addr = &bhdr->next_entry; \ } \ - if(!block_ptr) \ + if(!blk_offset) \ { \ __label__ redo; \ s32 translation_result; \ @@ -2643,10 +2661,11 @@ u8 function_cc *block_lookup_address_##type(u32 pc) \ redo: \ \ translation_recursion_level++; \ - ((u32 *)rom_translation_ptr)[0] = pc; \ - ((u32 **)rom_translation_ptr)[1] = NULL; \ - *block_ptr_address = (u32 *)rom_translation_ptr; \ - rom_translation_ptr += 8; \ + bhdr = (hashhdr_type*)rom_translation_ptr; \ + bhdr->pc_value = pc; \ + bhdr->next_entry = 0; \ + *blk_offset_addr = (u32)(rom_translation_ptr - rom_translation_cache);\ + rom_translation_ptr += sizeof(hashhdr_type); \ block_address = rom_translation_ptr + block_prologue_size; \ block_lookup_translate_##type(rom, 0); \ translation_recursion_level--; \ diff --git a/gpsp_config.h b/gpsp_config.h index 12da868..1012dcd 100644 --- a/gpsp_config.h +++ b/gpsp_config.h @@ -22,6 +22,7 @@ Check cpu_threaded.c for "memory tagging" for more info. */ /* Hash table size for ROM trans cache lookups */ -#define ROM_BRANCH_HASH_SIZE (1024 * 64) +#define ROM_BRANCH_HASH_BITS 16 +#define ROM_BRANCH_HASH_SIZE (1 << ROM_BRANCH_HASH_BITS) #endif diff --git a/psp/mips_emit.h b/psp/mips_emit.h index 6ff64de..32841e3 100644 --- a/psp/mips_emit.h +++ b/psp/mips_emit.h @@ -3213,7 +3213,7 @@ static void emit_phand( void init_emitter() { int i; // Initialize memory to a debuggable state - rom_cache_watermark = 0; + rom_cache_watermark = INITIAL_ROM_WATERMARK; // Generates the trampoline and helper stubs that we need u8 *translation_ptr = (u8*)&rom_translation_cache[0]; diff --git a/x86/x86_emit.h b/x86/x86_emit.h index 02cb474..c58fed2 100644 --- a/x86/x86_emit.h +++ b/x86/x86_emit.h @@ -2304,7 +2304,7 @@ extern u32 x86_table_info[3][16]; void init_emitter(void) { memcpy(x86_table_info, x86_table_data, sizeof(x86_table_data)); - rom_cache_watermark = 0; + rom_cache_watermark = INITIAL_ROM_WATERMARK; init_bios_hooks(); }