Make ROM hash table mechanism 64 bit compatible.

This commit is contained in:
David Guillen Fandos 2021-10-30 22:54:51 +02:00
parent c39f5391f0
commit 3f012afcda
6 changed files with 41 additions and 21 deletions

View File

@ -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.

2
cpu.h
View File

@ -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);

View File

@ -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--; \

View File

@ -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

View File

@ -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];

View File

@ -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();
}