nkeynes@359: /** nkeynes@561: * $Id$ nkeynes@359: * nkeynes@359: * SH4->x86 translation module nkeynes@359: * nkeynes@359: * Copyright (c) 2005 Nathan Keynes. nkeynes@359: * nkeynes@359: * This program is free software; you can redistribute it and/or modify nkeynes@359: * it under the terms of the GNU General Public License as published by nkeynes@359: * the Free Software Foundation; either version 2 of the License, or nkeynes@359: * (at your option) any later version. nkeynes@359: * nkeynes@359: * This program is distributed in the hope that it will be useful, nkeynes@359: * but WITHOUT ANY WARRANTY; without even the implied warranty of nkeynes@359: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the nkeynes@359: * GNU General Public License for more details. nkeynes@359: */ nkeynes@359: nkeynes@736: #ifndef lxdream_sh4trans_H nkeynes@736: #define lxdream_sh4trans_H 1 nkeynes@736: nkeynes@991: #include "xlat/xltcache.h" nkeynes@359: #include "dream.h" nkeynes@359: #include "mem.h" nkeynes@359: nkeynes@736: #ifdef __cplusplus nkeynes@736: extern "C" { nkeynes@736: #endif nkeynes@736: nkeynes@707: /** Maximum size of a translated instruction, in bytes. Current worst case seems nkeynes@707: * to be a BF/S followed by one of the long FMOVs. nkeynes@359: */ nkeynes@835: #define MAX_INSTRUCTION_SIZE 512 nkeynes@410: /** Maximum size of the translation epilogue (current real size is 116 bytes, so nkeynes@410: * allows a little room nkeynes@410: */ nkeynes@926: #define EPILOGUE_SIZE 136 nkeynes@571: nkeynes@571: /** Maximum number of recovery records for a translated block (2048 based on nkeynes@571: * 1 record per SH4 instruction in a 4K page). nkeynes@571: */ nkeynes@733: #define MAX_RECOVERY_SIZE 2049 nkeynes@585: nkeynes@1125: typedef void (*xlat_block_begin_callback_t)(); nkeynes@1125: typedef void (*xlat_block_end_callback_t)(); nkeynes@1125: nkeynes@585: /** nkeynes@359: */ nkeynes@1091: uint32_t sh4_translate_run_slice( uint32_t nanosecs ); nkeynes@585: nkeynes@585: /** nkeynes@669: * Initialize the translation engine (if required). Note xlat cache nkeynes@669: * must already be initialized. nkeynes@669: */ nkeynes@1091: void sh4_translate_init( void); nkeynes@669: nkeynes@669: /** nkeynes@359: * Translate the specified block of code starting from the specified start nkeynes@359: * address until the first branch/jump instruction. nkeynes@359: */ nkeynes@359: void *sh4_translate_basic_block( sh4addr_t start ); nkeynes@359: nkeynes@669: /** nkeynes@669: * Add a recovery record for the current code generation position, with the nkeynes@669: * specified instruction count nkeynes@669: */ nkeynes@669: void sh4_translate_add_recovery( uint32_t icount ); nkeynes@571: nkeynes@1125: /** nkeynes@1125: * Initialize shadow execution mode nkeynes@1125: */ nkeynes@1125: void sh4_shadow_init( void ); nkeynes@1125: nkeynes@359: extern uint8_t *xlat_output; nkeynes@571: extern struct xlat_recovery_record xlat_recovery[MAX_RECOVERY_SIZE]; nkeynes@604: extern xlat_cache_block_t xlat_current_block; nkeynes@571: extern uint32_t xlat_recovery_posn; nkeynes@359: nkeynes@526: /****************************************************************************** nkeynes@526: * Code generation - these methods must be provided by the nkeynes@526: * actual code gen (eg sh4x86.c) nkeynes@526: ******************************************************************************/ nkeynes@359: nkeynes@527: #define TARGET_X86 1 nkeynes@527: nkeynes@408: void sh4_translate_begin_block( sh4addr_t pc ); nkeynes@526: uint32_t sh4_translate_instruction( sh4addr_t pc ); nkeynes@359: void sh4_translate_end_block( sh4addr_t pc ); nkeynes@593: uint32_t sh4_translate_end_block_size(); nkeynes@669: void sh4_translate_emit_breakpoint( sh4vma_t pc ); nkeynes@1091: void sh4_translate_crashdump(); nkeynes@571: nkeynes@571: typedef void (*unwind_thunk_t)(void); nkeynes@571: nkeynes@571: /** nkeynes@1125: * Set instrumentation callbacks nkeynes@1125: */ nkeynes@1125: void sh4_translate_set_callbacks( xlat_block_begin_callback_t begin, xlat_block_end_callback_t end ); nkeynes@1125: nkeynes@1125: /** nkeynes@1125: * Enable/disable memory optimizations that bypass the mmu nkeynes@1125: */ nkeynes@1125: void sh4_translate_set_fastmem( gboolean flag ); nkeynes@1125: nkeynes@1125: /** nkeynes@1182: * Enable/disable basic block profiling nkeynes@1182: */ nkeynes@1182: void sh4_translate_set_profile_blocks( gboolean flag ); nkeynes@1182: nkeynes@1182: /** nkeynes@1182: * Get the boolean flag indicating whether block profiling is on. nkeynes@1182: */ nkeynes@1182: gboolean sh4_translate_get_profile_blocks(); nkeynes@1182: nkeynes@1182: /** nkeynes@1125: * Set the address spaces for the translated code. nkeynes@1125: */ nkeynes@1125: void sh4_translate_set_address_space( struct mem_region_fn **priv, struct mem_region_fn **user ); nkeynes@1125: nkeynes@1125: /** nkeynes@571: * From within the translator, (typically called from MMU exception handling routines) nkeynes@571: * immediately exit the current translation block (performing cleanup as necessary) and nkeynes@1091: * return to sh4_translate_run_slice(). Effectively a fast longjmp w/ xlat recovery. nkeynes@571: * nkeynes@571: * Note: The correct working of this method depends on the translator anticipating the nkeynes@571: * exception and generating the appropriate recovery block(s) - currently this means nkeynes@571: * that it should ONLY be called from within the context of a memory read or write. nkeynes@571: * nkeynes@571: * @param is_completion If TRUE, exit after completing the current instruction (effectively), nkeynes@571: * otherwise abort the current instruction with no effect. nkeynes@571: * @param thunk A function to execute after perform xlat recovery, but before returning nkeynes@571: * to run_slice. If NULL, control returns directly. nkeynes@571: * @return This method never returns. nkeynes@571: */ nkeynes@571: void sh4_translate_unwind_stack( gboolean is_completion, unwind_thunk_t thunk ); nkeynes@577: nkeynes@577: /** nkeynes@740: * Called when doing a break out of the translator - finalizes the system state up to nkeynes@740: * the end of the current instruction. nkeynes@577: */ nkeynes@740: void sh4_translate_exit_recover( ); nkeynes@591: nkeynes@591: /** nkeynes@941: * Called when doing a break out of the translator following a taken exception - nkeynes@941: * finalizes the system state up to the start of the current instruction. nkeynes@941: */ nkeynes@941: void sh4_translate_exception_exit_recover( ); nkeynes@941: nkeynes@941: /** nkeynes@669: * From within the translator, exit the current block at the end of the nkeynes@740: * current instruction, flush the translation cache (completely) nkeynes@740: * @return TRUE to perform a vm-exit/continue after the flush nkeynes@669: */ nkeynes@740: gboolean sh4_translate_flush_cache( void ); nkeynes@669: nkeynes@669: /** nkeynes@1186: * Given a block's use_list, remove all direct links to the block. nkeynes@1186: */ nkeynes@1186: void sh4_translate_unlink_block( void *use_list ); nkeynes@1186: nkeynes@1186: /** nkeynes@591: * Support function called from the translator when a breakpoint is hit. nkeynes@591: * Either returns immediately (to skip the breakpoint), or aborts the current nkeynes@591: * cycle and never returns. nkeynes@591: */ nkeynes@905: void FASTCALL sh4_translate_breakpoint_hit( sh4vma_t pc ); nkeynes@736: nkeynes@1091: /** nkeynes@1091: * Disassemble the given translated code block, and it's source SH4 code block nkeynes@1091: * side-by-side. The current native pc will be marked if non-null. nkeynes@1091: */ nkeynes@1091: void sh4_translate_disasm_block( FILE *out, void *code, sh4addr_t source_start, void *native_pc ); nkeynes@1091: nkeynes@1188: /** nkeynes@1188: * Dump the top N blocks in the SH4 translation cache nkeynes@1188: */ nkeynes@1188: void sh4_translate_dump_cache_by_activity( unsigned int topN ); nkeynes@1188: nkeynes@736: #ifdef __cplusplus nkeynes@736: } nkeynes@736: #endif nkeynes@736: nkeynes@760: #endif /* !lxdream_sh4trans_H */