1.1 --- a/src/sh4/shadow.c Fri Dec 02 18:18:04 2011 +1000
1.2 +++ b/src/sh4/shadow.c Wed Dec 14 21:51:55 2011 +1000
1.7 +#include "sh4/sh4core.h"
1.8 #include "sh4/sh4trans.h"
1.11 +#ifdef HAVE_FRAME_ADDRESS
1.12 +static FASTCALL __attribute__((noinline)) void *__first_arg(void *a, void *b) { return a; }
1.13 +#define INIT_EXCEPTIONS(label) goto *__first_arg(&&fnstart,&&label); fnstart:
1.14 +#define EXCEPTION_EXIT(exc) do{ *(((void **)__builtin_frame_address(0))+1) = exc; } while(0)
1.16 +#define INIT_EXCEPTIONS(label)
1.17 +#define EXCEPTION_EXIT() sh4_core_exit(CORE_EXIT_EXCEPTION)
1.27 + sh4addr_t exception_pc;
1.30 static struct sh4_registers shadow_sh4r;
1.33 #define IS_STORE_QUEUE(X) (((X)&0xFC000000) == 0xE0000000)
1.35 -static void log_mem_op( MemOp op, sh4addr_t addr, uint32_t value )
1.36 +static void log_mem_op( MemOp op, sh4addr_t addr, uint32_t value, int exception )
1.38 if( mem_log_posn == mem_log_size ) {
1.39 struct mem_log_entry *tmp = realloc(mem_log, mem_log_size * sizeof(struct mem_log_entry) * 2);
1.41 mem_log[mem_log_posn].op = op;
1.42 mem_log[mem_log_posn].addr = addr;
1.43 mem_log[mem_log_posn].value = value;
1.45 + mem_log[mem_log_posn].exception_pc = sh4r.pc;
1.47 + mem_log[mem_log_posn].exception_pc = -1;
1.56 -static int32_t check_mem_op( MemOp op, sh4addr_t addr, uint32_t value )
1.57 +static int32_t check_mem_op( MemOp op, sh4addr_t addr, uint32_t value, int *exception )
1.59 if( mem_check_posn >= mem_log_posn ) {
1.60 fprintf( stderr, "Unexpected interpreter memory operation: " );
1.61 @@ -107,6 +123,14 @@
1.62 print_mem_op(stderr, op, addr, value );
1.66 + if( mem_log[mem_check_posn].exception_pc != -1 ) {
1.67 + sh4_reraise_exception(mem_log[mem_check_posn].exception_pc);
1.73 return mem_log[mem_check_posn++].value;
1.76 @@ -172,120 +196,206 @@
1.77 if( memcmp( xsh4r->store_queue, esh4r->store_queue, sizeof(xsh4r->store_queue) ) != 0 ) {
1.79 fprintf( stderr, "Store queue Xlt =\n" );
1.80 - fwrite_dump( xsh4r->store_queue, sizeof(xsh4r->store_queue), stderr );
1.81 + fwrite_dump( (unsigned char *)xsh4r->store_queue, sizeof(xsh4r->store_queue), stderr );
1.82 fprintf( stderr, " Emu =\n" );
1.83 - fwrite_dump( esh4r->store_queue, sizeof(esh4r->store_queue), stderr );
1.84 + fwrite_dump( (unsigned char *)esh4r->store_queue, sizeof(esh4r->store_queue), stderr );
1.89 -static FASTCALL int32_t log_read_long( sh4addr_t addr )
1.90 +static FASTCALL int32_t log_read_long( sh4addr_t addr, void *exc )
1.92 - int32_t rv = real_address_space[addr>>12]->read_long(addr);
1.93 - log_mem_op( READ_LONG, addr, rv );
1.94 + INIT_EXCEPTIONS(except);
1.95 + int32_t rv = ((mem_read_exc_fn_t)real_address_space[addr>>12]->read_long)(addr, &&except);
1.96 + log_mem_op( READ_LONG, addr, rv, 0 );
1.99 + log_mem_op( READ_LONG, addr, rv, 1 );
1.100 + EXCEPTION_EXIT(exc);
1.103 -static FASTCALL int32_t log_read_word( sh4addr_t addr )
1.104 +static FASTCALL int32_t log_read_word( sh4addr_t addr, void *exc )
1.106 - int32_t rv = real_address_space[addr>>12]->read_word(addr);
1.107 - log_mem_op( READ_WORD, addr, rv );
1.108 + INIT_EXCEPTIONS(except);
1.109 + int32_t rv = ((mem_read_exc_fn_t)real_address_space[addr>>12]->read_word)(addr, &&except);
1.110 + log_mem_op( READ_WORD, addr, rv, 0 );
1.113 + log_mem_op( READ_WORD, addr, rv, 1 );
1.114 + EXCEPTION_EXIT(exc);
1.117 -static FASTCALL int32_t log_read_byte( sh4addr_t addr )
1.118 +static FASTCALL int32_t log_read_byte( sh4addr_t addr, void *exc )
1.120 - int32_t rv = real_address_space[addr>>12]->read_byte(addr);
1.121 - log_mem_op( READ_BYTE, addr, rv );
1.122 + INIT_EXCEPTIONS(except);
1.123 + int32_t rv = ((mem_read_exc_fn_t)real_address_space[addr>>12]->read_byte)(addr, &&except);
1.124 + log_mem_op( READ_BYTE, addr, rv, 0 );
1.127 + log_mem_op( READ_BYTE, addr, rv, 1 );
1.128 + EXCEPTION_EXIT(exc);
1.131 -static FASTCALL int32_t log_read_byte_for_write( sh4addr_t addr )
1.132 +static FASTCALL int32_t log_read_byte_for_write( sh4addr_t addr, void *exc )
1.134 - int32_t rv = real_address_space[addr>>12]->read_byte_for_write(addr);
1.135 - log_mem_op( READ_BYTE_FOR_WRITE, addr, rv );
1.136 + INIT_EXCEPTIONS(except);
1.137 + int32_t rv = ((mem_read_exc_fn_t)real_address_space[addr>>12]->read_byte_for_write)(addr, &&except);
1.138 + log_mem_op( READ_BYTE_FOR_WRITE, addr, rv, 0 );
1.141 + log_mem_op( READ_BYTE_FOR_WRITE, addr, rv, 1 );
1.142 + EXCEPTION_EXIT(exc);
1.145 -static FASTCALL void log_write_long( sh4addr_t addr, uint32_t val )
1.146 +static FASTCALL void log_write_long( sh4addr_t addr, uint32_t val, void *exc )
1.148 + INIT_EXCEPTIONS(except);
1.149 + ((mem_write_exc_fn_t)real_address_space[addr>>12]->write_long)(addr, val, &&except);
1.150 if( !IS_STORE_QUEUE(addr) )
1.151 - log_mem_op( WRITE_LONG, addr, val );
1.152 - real_address_space[addr>>12]->write_long(addr, val);
1.153 + log_mem_op( WRITE_LONG, addr, val, 0 );
1.156 + if( !IS_STORE_QUEUE(addr) )
1.157 + log_mem_op( WRITE_LONG, addr, val, 1 );
1.158 + EXCEPTION_EXIT(exc);
1.161 -static FASTCALL void log_write_word( sh4addr_t addr, uint32_t val )
1.162 +static FASTCALL void log_write_word( sh4addr_t addr, uint32_t val, void *exc )
1.164 + INIT_EXCEPTIONS(except);
1.165 + ((mem_write_exc_fn_t)real_address_space[addr>>12]->write_word)(addr, val, &&except);
1.166 if( !IS_STORE_QUEUE(addr) )
1.167 - log_mem_op( WRITE_WORD, addr, val );
1.168 - real_address_space[addr>>12]->write_word(addr, val);
1.169 + log_mem_op( WRITE_WORD, addr, val, 0 );
1.172 + if( !IS_STORE_QUEUE(addr) )
1.173 + log_mem_op( WRITE_WORD, addr, val, 1 );
1.174 + EXCEPTION_EXIT(exc);
1.177 -static FASTCALL void log_write_byte( sh4addr_t addr, uint32_t val )
1.178 +static FASTCALL void log_write_byte( sh4addr_t addr, uint32_t val, void *exc )
1.180 + INIT_EXCEPTIONS(except);
1.181 + ((mem_write_exc_fn_t)real_address_space[addr>>12]->write_byte)(addr, val, &&except);
1.182 if( !IS_STORE_QUEUE(addr) )
1.183 - log_mem_op( WRITE_BYTE, addr, val );
1.184 - real_address_space[addr>>12]->write_byte(addr, val);
1.185 + log_mem_op( WRITE_BYTE, addr, val, 0 );
1.188 + if( !IS_STORE_QUEUE(addr) )
1.189 + log_mem_op( WRITE_BYTE, addr, val, 1 );
1.190 + EXCEPTION_EXIT(exc);
1.193 -static FASTCALL void log_prefetch( sh4addr_t addr )
1.194 +static FASTCALL void log_prefetch( sh4addr_t addr, void *exc )
1.196 - log_mem_op( PREFETCH, addr, 0 );
1.197 - real_address_space[addr>>12]->prefetch(addr);
1.198 + INIT_EXCEPTIONS(except);
1.199 + ((mem_prefetch_exc_fn_t)real_address_space[addr>>12]->prefetch)(addr, &&except);
1.200 + log_mem_op( PREFETCH, addr, 0, 0 );
1.203 + log_mem_op( PREFETCH, addr, 0, 1 );
1.204 + EXCEPTION_EXIT(exc);
1.207 -static FASTCALL int32_t check_read_long( sh4addr_t addr )
1.208 +static FASTCALL int32_t check_read_long( sh4addr_t addr, void *exc )
1.210 - return check_mem_op( READ_LONG, addr, 0 );
1.212 + int32_t value = check_mem_op( READ_LONG, addr, 0, &except );
1.214 + EXCEPTION_EXIT(exc);
1.219 -static FASTCALL int32_t check_read_word( sh4addr_t addr )
1.220 +static FASTCALL int32_t check_read_word( sh4addr_t addr, void *exc )
1.222 - return check_mem_op( READ_WORD, addr, 0 );
1.224 + int32_t value = check_mem_op( READ_WORD, addr, 0, &except );
1.226 + EXCEPTION_EXIT(exc);
1.231 -static FASTCALL int32_t check_read_byte( sh4addr_t addr )
1.232 +static FASTCALL int32_t check_read_byte( sh4addr_t addr, void *exc )
1.234 - return check_mem_op( READ_BYTE, addr, 0 );
1.236 + int32_t value = check_mem_op( READ_BYTE, addr, 0, &except );
1.238 + EXCEPTION_EXIT(exc);
1.243 -static FASTCALL int32_t check_read_byte_for_write( sh4addr_t addr )
1.244 +static FASTCALL int32_t check_read_byte_for_write( sh4addr_t addr, void *exc )
1.246 - return check_mem_op( READ_BYTE_FOR_WRITE, addr, 0 );
1.248 + int32_t value = check_mem_op( READ_BYTE_FOR_WRITE, addr, 0, &except );
1.250 + EXCEPTION_EXIT(exc);
1.255 -static FASTCALL void check_write_long( sh4addr_t addr, uint32_t value )
1.256 +static FASTCALL void check_write_long( sh4addr_t addr, uint32_t value, void *exc )
1.258 - if( !IS_STORE_QUEUE(addr) )
1.259 - check_mem_op( WRITE_LONG, addr, value );
1.260 + if( !IS_STORE_QUEUE(addr) ) {
1.262 + check_mem_op( WRITE_LONG, addr, value, &except );
1.264 + EXCEPTION_EXIT(exc);
1.267 + real_address_space[addr>>12]->write_long(addr, value);
1.271 -static FASTCALL void check_write_word( sh4addr_t addr, uint32_t value )
1.272 +static FASTCALL void check_write_word( sh4addr_t addr, uint32_t value, void *exc )
1.274 - if( !IS_STORE_QUEUE(addr) )
1.275 - check_mem_op( WRITE_WORD, addr, value );
1.276 + if( !IS_STORE_QUEUE(addr) ) {
1.278 + check_mem_op( WRITE_WORD, addr, value, &except );
1.280 + EXCEPTION_EXIT(exc);
1.283 + real_address_space[addr>>12]->write_word(addr, value);
1.287 -static FASTCALL void check_write_byte( sh4addr_t addr, uint32_t value )
1.288 +static FASTCALL void check_write_byte( sh4addr_t addr, uint32_t value, void *exc )
1.290 - if( !IS_STORE_QUEUE(addr) )
1.291 - check_mem_op( WRITE_BYTE, addr, value );
1.292 + if( !IS_STORE_QUEUE(addr) ){
1.294 + check_mem_op( WRITE_BYTE, addr, value, &except );
1.296 + EXCEPTION_EXIT(exc);
1.299 + real_address_space[addr>>12]->write_byte(addr, value);
1.303 -static FASTCALL void check_prefetch( sh4addr_t addr )
1.304 +static FASTCALL void check_prefetch( sh4addr_t addr, void *exc )
1.306 - check_mem_op( PREFETCH, addr, 0 );
1.308 + check_mem_op( PREFETCH, addr, 0, &except );
1.310 + EXCEPTION_EXIT(exc);
1.314 -struct mem_region_fn log_fns = { log_read_long, log_write_long,
1.315 - log_read_word, log_write_word,
1.316 - log_read_byte, log_write_byte,
1.317 - NULL, NULL, log_prefetch, log_read_byte_for_write };
1.318 +struct mem_region_fn log_fns = {
1.319 + (mem_read_fn_t)log_read_long, (mem_write_fn_t)log_write_long,
1.320 + (mem_read_fn_t)log_read_word, (mem_write_fn_t)log_write_word,
1.321 + (mem_read_fn_t)log_read_byte, (mem_write_fn_t)log_write_byte,
1.322 + NULL, NULL, (mem_prefetch_fn_t)log_prefetch, (mem_read_fn_t)log_read_byte_for_write };
1.324 -struct mem_region_fn check_fns = { check_read_long, check_write_long,
1.325 - check_read_word, check_write_word,
1.326 - check_read_byte, check_write_byte,
1.327 - NULL, NULL, check_prefetch, check_read_byte_for_write };
1.328 +struct mem_region_fn check_fns = {
1.329 + (mem_read_fn_t)check_read_long, (mem_write_fn_t)check_write_long,
1.330 + (mem_read_fn_t)check_read_word, (mem_write_fn_t)check_write_word,
1.331 + (mem_read_fn_t)check_read_byte, (mem_write_fn_t)check_write_byte,
1.332 + NULL, NULL, (mem_prefetch_fn_t)check_prefetch, (mem_read_fn_t)check_read_byte_for_write };