<html>
<body>
<div id="body" style="background-color:#ffffff;" >
<table cellspacing="0" cellpadding="0" border="0" rules="cols">
<tr class="head" style="border-bottom-width:1px;border-bottom-style:solid;" ><td class="headtd" style="padding:0;padding-top:.2em;" colspan="4">Commit in <b><tt>lxdream/src/sh4</tt></b></td></tr>
<tr><td><tt><a href="#file1">sh4.c</a></tt></td><td id="added" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ddffdd;" align="right">+11</td><td></td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" nowrap="nowrap">dff55bdc4f46 -> ee6ce5804608</td></tr>
<tr class="alt" style=";" ><td><tt><a href="#file2">sh4core.h</a></tt></td><td id="addedalt" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ccf7cc;" align="right">+5</td><td></td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" nowrap="nowrap">dff55bdc4f46 -> ee6ce5804608</td></tr>
<tr><td><tt><a href="#file3">sh4x86.in</a></tt></td><td id="added" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ddffdd;" align="right">+6</td><td id="removed" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ffdddd;" align="right">-2</td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" nowrap="nowrap">dff55bdc4f46 -> ee6ce5804608</td></tr>
<tr class="alt" style=";" ><td><tt><a href="#file4">shadow.c</a></tt></td><td id="addedalt" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ccf7cc;" align="right">+165</td><td id="removed" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ffdddd;" align="right">-55</td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" nowrap="nowrap">dff55bdc4f46 -> ee6ce5804608</td></tr>
<tr><td></td><td id="added" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ddffdd;" align="right">+187</td><td id="removed" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ffdddd;" align="right">-57</td><td></td></tr>
</table>
<small id="info" style="color: #888888;" >4 modified files</small><br />
<div class="tasklist" style="padding:4px;border:1px dashed #000000;margin-top:1em;" ><ul>
<li><a href="#task1">FIXME: For now, disable this inlining when we're running in shadow mode -</a></li>
</ul></div>
<pre class="comment" style="white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;white-space:pre-wrap;word-wrap:break-word;padding:4px;border:1px dashed #000000;background-color:#ffffdd;" >
Handle memory exceptions thrown while in shadow mode
</pre>
<hr /><a name="file1" /><div class="file" style="border:1px solid #eeeeee;margin-top:1em;margin-bottom:1em;" >
<span class="pathname" style="font-family:monospace; float:right;" >lxdream/src/sh4</span><br />
<div class="fileheader" style="margin-bottom:.5em;" ><big><b>sh4.c</b></big> <small id="info" style="color: #888888;" >dff55bdc4f46 -> ee6ce5804608</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/src/sh4/sh4.c
+++ lxdream/src/sh4/sh4.c
@@ -550,6 +550,17 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > sh4r.in_delay_slot = 0;
}
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+void FASTCALL sh4_reraise_exception( sh4addr_t exception_pc )
+{
+ sh4r.spc = sh4r.pc;
+ sh4r.ssr = sh4_read_sr();
+ sh4r.sgr = sh4r.r[15];
+ sh4r.pc = exception_pc;
+ sh4r.new_pc = sh4r.pc + 2;
+ sh4_write_sr( sh4r.ssr |SR_MD|SR_BL|SR_RB );
+ sh4r.in_delay_slot = 0;
+}
+
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > void FASTCALL sh4_accept_interrupt( void )
{
uint32_t code = intc_accept_interrupt();
</pre></div>
<hr /><a name="file2" /><div class="file" style="border:1px solid #eeeeee;margin-top:1em;margin-bottom:1em;" >
<span class="pathname" style="font-family:monospace; float:right;" >lxdream/src/sh4</span><br />
<div class="fileheader" style="margin-bottom:.5em;" ><big><b>sh4core.h</b></big> <small id="info" style="color: #888888;" >dff55bdc4f46 -> ee6ce5804608</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/src/sh4/sh4core.h
+++ lxdream/src/sh4/sh4core.h
@@ -243,6 +243,11 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > void FASTCALL sh4_accept_interrupt( void );
/**
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ * Helper method to update the SH4 registers for an exception, without
+ * touching the MMU registers. Mainly for use in shadow mode.
+ */
+void FASTCALL sh4_reraise_exception( sh4addr_t exception_pc );
+/**
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > * Complete the current instruction as part of a core exit. Prevents the
* system from being left in an inconsistent state when an exit is
* triggered during a memory write.
</pre></div>
<hr /><a name="file3" /><div class="file" style="border:1px solid #eeeeee;margin-top:1em;margin-bottom:1em;" >
<span class="pathname" style="font-family:monospace; float:right;" >lxdream/src/sh4</span><br />
<div class="fileheader" style="margin-bottom:.5em;" ><big><b>sh4x86.in</b></big> <small id="info" style="color: #888888;" >dff55bdc4f46 -> ee6ce5804608</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/src/sh4/sh4x86.in
+++ lxdream/src/sh4/sh4x86.in
@@ -623,7 +623,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > static void jump_next_block_fixed_pc( sh4addr_t pc )
{
if( IS_IN_ICACHE(pc) ) {
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- if( sh4_x86.sh4_mode != SH4_MODE_UNKNOWN ) {
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ if( sh4_x86.sh4_mode != SH4_MODE_UNKNOWN && sh4_x86.end_callback == NULL ) {
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > /* Fixed address, in cache, and fixed SH4 mode - generate a call to the
* fetch-and-backpatch routine, which will replace the call with a branch */
emit_translate_and_backpatch();
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -2683,7 +2683,11 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > COUNT_INST(I_FTRV);
check_fpuen();
if( sh4_x86.double_prec == 0 ) {
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- if( sh4_x86.sse3_enabled ) {
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ if( sh4_x86.sse3_enabled && sh4_x86.begin_callback == NULL ) {
<a name="task1" />+ /* <span class="task" style="background-color:#ffff00;" >FIXME</span>: For now, disable this inlining when we're running in shadow mode -
+ * it gives slightly different results from the emu core. Need to
+ * fix the precision so both give the right results.
+ */
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > MOVAPS_rbpdisp_xmm( REG_OFFSET(fr[1][0]), 1 ); // M1 M0 M3 M2
MOVAPS_rbpdisp_xmm( REG_OFFSET(fr[1][4]), 0 ); // M5 M4 M7 M6
MOVAPS_rbpdisp_xmm( REG_OFFSET(fr[1][8]), 3 ); // M9 M8 M11 M10
</pre></div>
<hr /><a name="file4" /><div class="file" style="border:1px solid #eeeeee;margin-top:1em;margin-bottom:1em;" >
<span class="pathname" style="font-family:monospace; float:right;" >lxdream/src/sh4</span><br />
<div class="fileheader" style="margin-bottom:.5em;" ><big><b>shadow.c</b></big> <small id="info" style="color: #888888;" >dff55bdc4f46 -> ee6ce5804608</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/src/sh4/shadow.c
+++ lxdream/src/sh4/shadow.c
@@ -24,9 +24,19 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > #include "clock.h"
#include "mem.h"
#include "sh4/sh4.h"
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+#include "sh4/sh4core.h"
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > #include "sh4/sh4trans.h"
#include "sh4/mmu.h"
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+#ifdef HAVE_FRAME_ADDRESS
+static FASTCALL __attribute__((noinline)) void *__first_arg(void *a, void *b) { return a; }
+#define INIT_EXCEPTIONS(label) goto *__first_arg(&&fnstart,&&label); fnstart:
+#define EXCEPTION_EXIT(exc) do{ *(((void **)__builtin_frame_address(0))+1) = exc; } while(0)
+#else
+#define INIT_EXCEPTIONS(label)
+#define EXCEPTION_EXIT() sh4_core_exit(CORE_EXIT_EXCEPTION)
+#endif
+
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > typedef enum {
READ_LONG,
WRITE_LONG,
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -45,6 +55,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > MemOp op;
sh4addr_t addr;
uint32_t value;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ sh4addr_t exception_pc;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > };
static struct sh4_registers shadow_sh4r;
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -59,7 +70,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >
#define IS_STORE_QUEUE(X) (((X)&0xFC000000) == 0xE0000000)
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-static void log_mem_op( MemOp op, sh4addr_t addr, uint32_t value )
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+static void log_mem_op( MemOp op, sh4addr_t addr, uint32_t value<span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >, int exception</span> )
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > {
if( mem_log_posn == mem_log_size ) {
struct mem_log_entry *tmp = realloc(mem_log, mem_log_size * sizeof(struct mem_log_entry) * 2);
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -70,6 +81,11 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > mem_log[mem_log_posn].op = op;
mem_log[mem_log_posn].addr = addr;
mem_log[mem_log_posn].value = value;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ if( exception ) {
+ mem_log[mem_log_posn].exception_pc = sh4r.pc;
+ } else {
+ mem_log[mem_log_posn].exception_pc = -1;
+ }
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > mem_log_posn++;
}
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -89,7 +105,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
}
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-static int32_t check_mem_op( MemOp op, sh4addr_t addr, uint32_t value )
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+static int32_t check_mem_op( MemOp op, sh4addr_t addr, uint32_t value<span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >, int *exception</span> )
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > {
if( mem_check_posn >= mem_log_posn ) {
fprintf( stderr, "Unexpected interpreter memory operation: " );
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -107,6 +123,14 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > print_mem_op(stderr, op, addr, value );
abort();
}
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+
+ if( mem_log[mem_check_posn].exception_pc != -1 ) {
+ sh4_reraise_exception(mem_log[mem_check_posn].exception_pc);
+ *exception = 1;
+ } else {
+ *exception = 0;
+ }
+
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > return mem_log[mem_check_posn++].value;
}
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -172,120 +196,206 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > if( memcmp( xsh4r->store_queue, esh4r->store_queue, sizeof(xsh4r->store_queue) ) != 0 ) {
isgood = FALSE;
fprintf( stderr, "Store queue Xlt =\n" );
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- fwrite_dump( xsh4r->store_queue, sizeof(xsh4r->store_queue), stderr );
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ fwrite_dump( <span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >(unsigned char *)</span>xsh4r->store_queue, sizeof(xsh4r->store_queue), stderr );
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > fprintf( stderr, " Emu =\n" );
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- fwrite_dump( esh4r->store_queue, sizeof(esh4r->store_queue), stderr );
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ fwrite_dump( <span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >(unsigned char *)</span>esh4r->store_queue, sizeof(esh4r->store_queue), stderr );
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
return isgood;
}
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-static FASTCALL int32_t log_read_long( sh4addr_t addr )
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+static FASTCALL int32_t log_read_long( sh4addr_t addr<span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >, void *exc</span> )
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > {
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- int32_t rv = real_address_space[addr>>12]->read_long(addr);
- log_mem_op( READ_LONG, addr, rv );
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ INIT_EXCEPTIONS(except);
+ int32_t rv = ((mem_read_exc_fn_t)real_address_space[addr>>12]->read_long)(addr, &&except);
+ log_mem_op( READ_LONG, addr, rv, 0 );
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > return rv;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+except:
+ log_mem_op( READ_LONG, addr, rv, 1 );
+ EXCEPTION_EXIT(exc);
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-static FASTCALL int32_t log_read_word( sh4addr_t addr )
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+static FASTCALL int32_t log_read_word( sh4addr_t addr<span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >, void *exc</span> )
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > {
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- int32_t rv = real_address_space[addr>>12]->read_word(addr);
- log_mem_op( READ_WORD, addr, rv );
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ INIT_EXCEPTIONS(except);
+ int32_t rv = ((mem_read_exc_fn_t)real_address_space[addr>>12]->read_word)(addr, &&except);
+ log_mem_op( READ_WORD, addr, rv, 0 );
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > return rv;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+except:
+ log_mem_op( READ_WORD, addr, rv, 1 );
+ EXCEPTION_EXIT(exc);
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-static FASTCALL int32_t log_read_byte( sh4addr_t addr )
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+static FASTCALL int32_t log_read_byte( sh4addr_t addr<span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >, void *exc</span> )
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > {
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- int32_t rv = real_address_space[addr>>12]->read_byte(addr);
- log_mem_op( READ_BYTE, addr, rv );
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ INIT_EXCEPTIONS(except);
+ int32_t rv = ((mem_read_exc_fn_t)real_address_space[addr>>12]->read_byte)(addr, &&except);
+ log_mem_op( READ_BYTE, addr, rv, 0 );
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > return rv;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+except:
+ log_mem_op( READ_BYTE, addr, rv, 1 );
+ EXCEPTION_EXIT(exc);
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-static FASTCALL int32_t log_read_byte_for_write( sh4addr_t addr )
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+static FASTCALL int32_t log_read_byte_for_write( sh4addr_t addr<span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >, void *exc</span> )
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > {
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- int32_t rv = real_address_space[addr>>12]->read_byte_for_write(addr);
- log_mem_op( READ_BYTE_FOR_WRITE, addr, rv );
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ INIT_EXCEPTIONS(except);
+ int32_t rv = ((mem_read_exc_fn_t)real_address_space[addr>>12]->read_byte_for_write)(addr, &&except);
+ log_mem_op( READ_BYTE_FOR_WRITE, addr, rv, 0 );
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > return rv;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+except:
+ log_mem_op( READ_BYTE_FOR_WRITE, addr, rv, 1 );
+ EXCEPTION_EXIT(exc);
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-static FASTCALL void log_write_long( sh4addr_t addr, uint32_t val )
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+static FASTCALL void log_write_long( sh4addr_t addr, uint32_t val<span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >, void *exc</span> )
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > {
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ INIT_EXCEPTIONS(except);
+ ((mem_write_exc_fn_t)real_address_space[addr>>12]->write_long)(addr, val, &&except);
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > if( !IS_STORE_QUEUE(addr) )
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- log_mem_op( WRITE_LONG, addr, val );
- real_address_space[addr>>12]->write_long(addr, val);
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ log_mem_op( WRITE_LONG, addr, val, 0 );
+ return;
+except:
+ if( !IS_STORE_QUEUE(addr) )
+ log_mem_op( WRITE_LONG, addr, val, 1 );
+ EXCEPTION_EXIT(exc);
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-static FASTCALL void log_write_word( sh4addr_t addr, uint32_t val )
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+static FASTCALL void log_write_word( sh4addr_t addr, uint32_t val<span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >, void *exc</span> )
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > {
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ INIT_EXCEPTIONS(except);
+ ((mem_write_exc_fn_t)real_address_space[addr>>12]->write_word)(addr, val, &&except);
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > if( !IS_STORE_QUEUE(addr) )
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- log_mem_op( WRITE_WORD, addr, val );
- real_address_space[addr>>12]->write_word(addr, val);
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ log_mem_op( WRITE_WORD, addr, val, 0 );
+ return;
+except:
+ if( !IS_STORE_QUEUE(addr) )
+ log_mem_op( WRITE_WORD, addr, val, 1 );
+ EXCEPTION_EXIT(exc);
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-static FASTCALL void log_write_byte( sh4addr_t addr, uint32_t val )
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+static FASTCALL void log_write_byte( sh4addr_t addr, uint32_t val<span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >, void *exc</span> )
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > {
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ INIT_EXCEPTIONS(except);
+ ((mem_write_exc_fn_t)real_address_space[addr>>12]->write_byte)(addr, val, &&except);
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > if( !IS_STORE_QUEUE(addr) )
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- log_mem_op( WRITE_BYTE, addr, val );
- real_address_space[addr>>12]->write_byte(addr, val);
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ log_mem_op( WRITE_BYTE, addr, val, 0 );
+ return;
+except:
+ if( !IS_STORE_QUEUE(addr) )
+ log_mem_op( WRITE_BYTE, addr, val, 1 );
+ EXCEPTION_EXIT(exc);
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-static FASTCALL void log_prefetch( sh4addr_t addr )
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+static FASTCALL void log_prefetch( sh4addr_t addr<span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >, void *exc</span> )
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > {
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- log_mem_op( PREFETCH, addr, 0 );
- real_address_space[addr>>12]->prefetch(addr);
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ INIT_EXCEPTIONS(except);
+ ((mem_prefetch_exc_fn_t)real_address_space[addr>>12]->prefetch)(addr, &&except);
+ log_mem_op( PREFETCH, addr, 0, 0 );
+ return;
+except:
+ log_mem_op( PREFETCH, addr, 0, 1 );
+ EXCEPTION_EXIT(exc);
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-static FASTCALL int32_t check_read_long( sh4addr_t addr )
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+static FASTCALL int32_t check_read_long( sh4addr_t addr<span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >, void *exc</span> )
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > {
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- return check_mem_op( READ_LONG, addr, 0 );
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ int except;
+ int32_t value = check_mem_op( READ_LONG, addr, 0, &except );
+ if( except ) {
+ EXCEPTION_EXIT(exc);
+ }
+ return value;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-static FASTCALL int32_t check_read_word( sh4addr_t addr )
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+static FASTCALL int32_t check_read_word( sh4addr_t addr<span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >, void *exc</span> )
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > {
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- return check_mem_op( READ_WORD, addr, 0 );
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ int except;
+ int32_t value = check_mem_op( READ_WORD, addr, 0, &except );
+ if( except ) {
+ EXCEPTION_EXIT(exc);
+ }
+ return value;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-static FASTCALL int32_t check_read_byte( sh4addr_t addr )
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+static FASTCALL int32_t check_read_byte( sh4addr_t addr<span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >, void *exc</span> )
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > {
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- return check_mem_op( READ_BYTE, addr, 0 );
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ int except;
+ int32_t value = check_mem_op( READ_BYTE, addr, 0, &except );
+ if( except ) {
+ EXCEPTION_EXIT(exc);
+ }
+ return value;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-static FASTCALL int32_t check_read_byte_for_write( sh4addr_t addr )
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+static FASTCALL int32_t check_read_byte_for_write( sh4addr_t addr<span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >, void *exc</span> )
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > {
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- return check_mem_op( READ_BYTE_FOR_WRITE, addr, 0 );
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ int except;
+ int32_t value = check_mem_op( READ_BYTE_FOR_WRITE, addr, 0, &except );
+ if( except ) {
+ EXCEPTION_EXIT(exc);
+ }
+ return value;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-static FASTCALL void check_write_long( sh4addr_t addr, uint32_t value )
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+static FASTCALL void check_write_long( sh4addr_t addr, uint32_t value<span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >, void *exc</span> )
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > {
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- if( !IS_STORE_QUEUE(addr) )
- check_mem_op( WRITE_LONG, addr, value );
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ if( !IS_STORE_QUEUE(addr) ) {
+ int except;
+ check_mem_op( WRITE_LONG, addr, value, &except );
+ if( except ) {
+ EXCEPTION_EXIT(exc);
+ }
+ } else {
+ real_address_space[addr>>12]->write_long(addr, value);
+ }
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-static FASTCALL void check_write_word( sh4addr_t addr, uint32_t value )
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+static FASTCALL void check_write_word( sh4addr_t addr, uint32_t value<span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >, void *exc</span> )
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > {
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- if( !IS_STORE_QUEUE(addr) )
- check_mem_op( WRITE_WORD, addr, value );
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ if( !IS_STORE_QUEUE(addr) ) {
+ int except;
+ check_mem_op( WRITE_WORD, addr, value, &except );
+ if( except ) {
+ EXCEPTION_EXIT(exc);
+ }
+ } else {
+ real_address_space[addr>>12]->write_word(addr, value);
+ }
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-static FASTCALL void check_write_byte( sh4addr_t addr, uint32_t value )
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+static FASTCALL void check_write_byte( sh4addr_t addr, uint32_t value<span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >, void *exc</span> )
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > {
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- if( !IS_STORE_QUEUE(addr) )
- check_mem_op( WRITE_BYTE, addr, value );
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ if( !IS_STORE_QUEUE(addr) ){
+ int except;
+ check_mem_op( WRITE_BYTE, addr, value, &except );
+ if( except ) {
+ EXCEPTION_EXIT(exc);
+ }
+ } else {
+ real_address_space[addr>>12]->write_byte(addr, value);
+ }
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-static FASTCALL void check_prefetch( sh4addr_t addr )
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+static FASTCALL void check_prefetch( sh4addr_t addr<span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >, void *exc</span> )
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > {
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- check_mem_op( PREFETCH, addr, 0 );
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ int except;
+ check_mem_op( PREFETCH, addr, 0, &except );
+ if( except ) {
+ EXCEPTION_EXIT(exc);
+ }
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-struct mem_region_fn log_fns = { log_read_long, log_write_long,
- log_read_word, log_write_word,
- log_read_byte, log_write_byte,
- NULL, NULL, log_prefetch, log_read_byte_for_write };
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+struct mem_region_fn log_fns = {
+ (mem_read_fn_t)log_read_long, (mem_write_fn_t)log_write_long,
+ (mem_read_fn_t)log_read_word, (mem_write_fn_t)log_write_word,
+ (mem_read_fn_t)log_read_byte, (mem_write_fn_t)log_write_byte,
+ NULL, NULL, (mem_prefetch_fn_t)log_prefetch, (mem_read_fn_t)log_read_byte_for_write };
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-struct mem_region_fn check_fns = { check_read_long, check_write_long,
- check_read_word, check_write_word,
- check_read_byte, check_write_byte,
- NULL, NULL, check_prefetch, check_read_byte_for_write };
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+struct mem_region_fn check_fns = {
+ (mem_read_fn_t)check_read_long, (mem_write_fn_t)check_write_long,
+ (mem_read_fn_t)check_read_word, (mem_write_fn_t)check_write_word,
+ (mem_read_fn_t)check_read_byte, (mem_write_fn_t)check_write_byte,
+ NULL, NULL, (mem_prefetch_fn_t)check_prefetch, (mem_read_fn_t)check_read_byte_for_write };
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >
</pre></div>
<center><small>Chaos Theory</small></center>
</div></body></html>