nkeynes@359: /** nkeynes@586: * $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@586: #include "sh4/xltcache.h" nkeynes@359: #include "dream.h" nkeynes@359: #include "mem.h" nkeynes@359: nkeynes@359: /** Maximum size of a translated instruction, in bytes. This includes potentially nkeynes@359: * writing the entire epilogue nkeynes@359: */ nkeynes@389: #define MAX_INSTRUCTION_SIZE 256 nkeynes@410: /** Maximum size of the translation epilogue (current real size is 116 bytes, so nkeynes@410: * allows a little room nkeynes@410: */ nkeynes@410: #define EPILOGUE_SIZE 128 nkeynes@586: nkeynes@586: /** Maximum number of recovery records for a translated block (2048 based on nkeynes@586: * 1 record per SH4 instruction in a 4K page). nkeynes@586: */ nkeynes@586: #define MAX_RECOVERY_SIZE 2048 nkeynes@586: nkeynes@359: /** nkeynes@586: * Translation flag - exit the current block but continue (eg exception handling) nkeynes@586: */ nkeynes@586: #define XLAT_EXIT_CONTINUE 1 nkeynes@359: nkeynes@586: /** nkeynes@586: * Translation flag - exit the current block and halt immediately (eg fatal error) nkeynes@586: */ nkeynes@586: #define XLAT_EXIT_HALT 2 nkeynes@586: nkeynes@586: /** nkeynes@586: * Translation flag - exit the current block and halt immediately for a system nkeynes@586: * breakpoint. nkeynes@586: */ nkeynes@586: #define XLAT_EXIT_BREAKPOINT 3 nkeynes@586: nkeynes@586: /** nkeynes@586: * Translation flag - exit the current block and continue after performing a full nkeynes@586: * system reset (dreamcast_reset()) nkeynes@586: */ nkeynes@586: #define XLAT_EXIT_SYSRESET 4 nkeynes@586: nkeynes@586: /** nkeynes@359: */ nkeynes@359: uint32_t sh4_xlat_run_slice( uint32_t nanosecs ); nkeynes@359: nkeynes@359: /** nkeynes@586: * Return true if translated code is currently running nkeynes@586: */ nkeynes@586: gboolean sh4_xlat_is_running(); nkeynes@586: nkeynes@586: /** 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@586: nkeynes@359: extern uint8_t *xlat_output; nkeynes@586: extern struct xlat_recovery_record xlat_recovery[MAX_RECOVERY_SIZE]; nkeynes@586: 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: #define TARGET_X86_64 2 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@586: nkeynes@586: typedef void (*unwind_thunk_t)(void); nkeynes@586: nkeynes@586: /** nkeynes@586: * From within the translator, (typically called from MMU exception handling routines) nkeynes@586: * immediately exit the current translation block (performing cleanup as necessary) and nkeynes@586: * return to sh4_xlat_run_slice(). Effectively a fast longjmp w/ xlat recovery. nkeynes@586: * nkeynes@586: * Note: The correct working of this method depends on the translator anticipating the nkeynes@586: * exception and generating the appropriate recovery block(s) - currently this means nkeynes@586: * that it should ONLY be called from within the context of a memory read or write. nkeynes@586: * nkeynes@586: * @param is_completion If TRUE, exit after completing the current instruction (effectively), nkeynes@586: * otherwise abort the current instruction with no effect. nkeynes@586: * @param thunk A function to execute after perform xlat recovery, but before returning nkeynes@586: * to run_slice. If NULL, control returns directly. nkeynes@586: * @return This method never returns. nkeynes@586: */ nkeynes@586: void sh4_translate_unwind_stack( gboolean is_completion, unwind_thunk_t thunk ); nkeynes@586: nkeynes@586: /** nkeynes@586: * From within the translator, immediately exit the current translation block with nkeynes@586: * the specified exit code (one of the XLAT_EXIT_* values). nkeynes@586: */ nkeynes@586: void sh4_translate_exit( int exit_code );