<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</tt></b></td></tr>
<tr><td><tt><a href="#file1">eventq.h</a></tt></td><td id="added" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ddffdd;" align="right">+1</td><td></td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" nowrap="nowrap">742c073f353f -> 4cac5e474d4c</td></tr>
<tr class="alt" style=";" ><td><tt>sh4/<a href="#file2">sh4.c</a></tt></td><td id="addedalt" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ccf7cc;" align="right">+8</td><td></td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" nowrap="nowrap">742c073f353f -> 4cac5e474d4c</td></tr>
<tr><td><tt>   /<a href="#file3">sh4trans.c</a></tt></td><td id="added" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ddffdd;" align="right">+13</td><td id="removed" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ffdddd;" align="right">-22</td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" nowrap="nowrap">742c073f353f -> 4cac5e474d4c</td></tr>
<tr class="alt" style=";" ><td><tt>   /<a href="#file4">sh4x86.in</a></tt></td><td id="addedalt" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ccf7cc;" align="right">+100</td><td id="removed" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ffdddd;" align="right">-47</td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" nowrap="nowrap">742c073f353f -> 4cac5e474d4c</td></tr>
<tr><td><tt>test/<a href="#file5">testsh4x86.c</a></tt></td><td id="added" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ddffdd;" align="right">+1</td><td></td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" nowrap="nowrap">742c073f353f -> 4cac5e474d4c</td></tr>
<tr class="alt" style=";" ><td><tt>xlat/x86/<a href="#file6">amd64abi.h</a></tt></td><td id="addedalt" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ccf7cc;" align="right">+3</td><td></td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" nowrap="nowrap">742c073f353f -> 4cac5e474d4c</td></tr>
<tr><td><tt>        /<a href="#file7">ia32abi.h</a></tt></td><td id="added" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ddffdd;" align="right">+3</td><td></td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" nowrap="nowrap">742c073f353f -> 4cac5e474d4c</td></tr>
<tr class="alt" style=";" ><td><tt>        /<a href="#file8">x86op.h</a></tt></td><td id="addedalt" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ccf7cc;" align="right">+7</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">742c073f353f -> 4cac5e474d4c</td></tr>
<tr><td></td><td id="added" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ddffdd;" align="right">+136</td><td id="removed" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ffdddd;" align="right">-71</td><td></td></tr>
</table>
<small id="info" style="color: #888888;" >8 modified files</small><br />
<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;" >
Rearrange the main translation loop to allow translated blocks to jump
directly to their successors without needing to return to the main loop
in between. Shaves about 6% off the core runtime.
</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</span><br />
<div class="fileheader" style="margin-bottom:.5em;" ><big><b>eventq.h</b></big> <small id="info" style="color: #888888;" >742c073f353f -> 4cac5e474d4c</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/src/eventq.h
+++ lxdream/src/eventq.h
@@ -80,6 +80,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > #define EVENT_TMU2 99
 #define EVENT_GUNPOS 100
 
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+#define EVENT_ENDTIMESLICE 127
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > #ifdef __cplusplus
 }
 #endif
</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>sh4.c</b></big> <small id="info" style="color: #888888;" >742c073f353f -> 4cac5e474d4c</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/src/sh4/sh4.c
+++ lxdream/src/sh4/sh4.c
@@ -153,6 +153,13 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > static gboolean sh4_running = FALSE;
 struct sh4_icache_struct sh4_icache = { NULL, -1, -1, 0 };
 
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+/* At the moment this is a dummy event to mark the end of the
+ * timeslice
+ */
+void sh4_dummy_event(int eventid)
+{
+}
+
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > void sh4_translate_set_enabled( gboolean use )
 {
     // No-op if the translator was not built
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -172,6 +179,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > void sh4_init(void)
 {
     register_io_regions( mmio_list_sh4mmio );
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+    register_event_callback( EVENT_ENDTIMESLICE, sh4_dummy_event );
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     MMU_init();
     TMU_init();
     xlat_cache_init();
</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>sh4trans.c</b></big> <small id="info" style="color: #888888;" >742c073f353f -> 4cac5e474d4c</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/src/sh4/sh4trans.c
+++ lxdream/src/sh4/sh4trans.c
@@ -33,7 +33,8 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > uint32_t sh4_translate_run_slice( uint32_t nanosecs ) 
 {
     void * (*code)() = NULL;
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-    while( sh4r.slice_cycle < nanosecs ) {
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+    event_schedule( EVENT_ENDTIMESLICE, nanosecs );
+    for(;;) {
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >         if( sh4r.event_pending <= sh4r.slice_cycle ) {
             if( sh4r.event_types & PENDING_EVENT ) {
                 event_execute();
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -43,33 +44,23 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >                 sh4_accept_interrupt();
                 code = NULL;
             }
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+            if( sh4r.slice_cycle >= nanosecs )
+                return nanosecs;
</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( code == NULL ) {
-            if( IS_SYSCALL(sh4r.pc) ) {
-                uint32_t pc = sh4r.pc;
-                sh4r.pc = sh4r.pr;
-                sh4r.in_delay_slot = 0;
-                syscall_invoke( pc );
-            }
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+        if( IS_SYSCALL(sh4r.pc) ) {
+            uint32_t pc = sh4r.pc;
+            sh4r.pc = sh4r.pr;
+            sh4r.in_delay_slot = 0;
+            syscall_invoke( pc );
+        }
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > 
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-            code = xlat_get_code_by_vma( sh4r.pc );
-            if( code == NULL || sh4r.xlat_sh4_mode != XLAT_BLOCK_MODE(code) ) {
-                code = sh4_translate_basic_block( sh4r.pc );
-            }
-        } else if( sh4r.xlat_sh4_mode != XLAT_BLOCK_MODE(code) ) {
-            if( !IS_IN_ICACHE(sh4r.pc) ) {
-                /* If TLB is off, we may have gotten here without updating
-                 * the icache, so do it now. This should never fail, so...
-                 */
-                mmu_update_icache(sh4r.pc);
-                assert( IS_IN_ICACHE(sh4r.pc) ); 
-            }
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+        code = xlat_get_code_by_vma( sh4r.pc );
+        if( code == NULL || sh4r.xlat_sh4_mode != XLAT_BLOCK_MODE(code) ) {
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >             code = sh4_translate_basic_block( sh4r.pc );
         }
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-        code<span id="removedchars" style="background-color:#ff9999;font-weight:bolder;" > = code</span>();
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+        code();
</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 nanosecs;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
 
 uint8_t *xlat_output;
</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>sh4x86.in</b></big> <small id="info" style="color: #888888;" >742c073f353f -> 4cac5e474d4c</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/src/sh4/sh4x86.in
+++ lxdream/src/sh4/sh4x86.in
@@ -71,6 +71,8 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > #define DELAY_PC 1
 #define DELAY_PC_PR 2
 
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+#define SH4_MODE_UNKNOWN -1
+
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > struct backpatch_record {
     uint32_t fixup_offset;
     uint32_t fixup_icount;
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -84,6 +86,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >  */
 struct sh4_x86_state {
     int in_delay_slot;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+    uint8_t *code;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     gboolean fpuen_checked; /* true if we've already checked fpu enabled. */
     gboolean branch_taken; /* true if we branched unconditionally */
     gboolean double_prec; /* true if FPU is in double-precision mode */
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -91,6 +94,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     gboolean sse3_enabled; /* true if host supports SSE3 instructions */
     uint32_t block_start_pc;
     uint32_t stack_posn;   /* Trace stack height for alignment purposes */
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+    uint32_t sh4_mode;     /* Mirror of sh4r.xlat_sh4_mode */
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     int tstate;
 
     /* mode flags */
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -171,7 +175,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >         fprintf( out, "%c%016lx: %-30s %-40s", (target_pc == (uintptr_t)native_pc ? '*' : ' '),
                       target_pc, op, buf );
 #else
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-        fprintf( out, "%c%08x: %-30s %-40s", (target_pc == (uintptr_t)native_pc ? '*' : ' '),
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+        fprintf( out, "%c%08<span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >l</span>x: %-30s %-40s", (target_pc == (uintptr_t)native_pc ? '*' : ' '),
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >                       target_pc, op, buf );
 #endif        
         if( source_recov_table < source_recov_end && 
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -249,6 +253,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > #define SETNE_t()        SETCCB_cc_rbpdisp(X86_COND_NE,R_T)
 #define SETC_r8(r1)      SETCCB_cc_r8(X86_COND_C, r1)
 #define JAE_label(label) JCC_cc_rel8(X86_COND_AE,-1); MARK_JMP8(label)
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+#define JBE_label(label) JCC_cc_rel8(X86_COND_BE,-1); MARK_JMP8(label)
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > #define JE_label(label)  JCC_cc_rel8(X86_COND_E,-1); MARK_JMP8(label)
 #define JGE_label(label) JCC_cc_rel8(X86_COND_GE,-1); MARK_JMP8(label)
 #define JNA_label(label) JCC_cc_rel8(X86_COND_NA,-1); MARK_JMP8(label)
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -317,7 +322,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > /* Exception checks - Note that all exception checks will clobber EAX */
 
 #define check_priv( ) \
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-    if( (sh4<span id="removedchars" style="background-color:#ff9999;font-weight:bolder;" >r.xlat_</span>sh4_mode & SR_MD) == 0 ) { \
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+    if( (sh4<span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >_x86.</span>sh4_mode & SR_MD) == 0 ) { \
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >         if( sh4_x86.in_delay_slot ) { \
             exit_block_exc(EXC_SLOT_ILLEGAL, (pc-2) ); \
         } else { \
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -365,7 +370,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     TESTL_imms_r32( 0x00000007, x86reg ); \
     JNE_exc(EXC_DATA_ADDR_WRITE);
 
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-#define address_space() ((sh4<span id="removedchars" style="background-color:#ff9999;font-weight:bolder;" >r.xlat_</span>sh4_mode&SR_MD) ? (uintptr_t)sh4_address_space : (uintptr_t)sh4_user_address_space)
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+#define address_space() ((sh4<span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >_x86.</span>sh4_mode&SR_MD) ? (uintptr_t)sh4_address_space : (uintptr_t)sh4_user_address_space)
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > 
 #define UNDEF(ir)
 /* Note: For SR.MD == 1 && MMUCR.AT == 0, there are no memory exceptions, so 
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -375,7 +380,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > static void call_read_func(int addr_reg, int value_reg, int offset, int pc)
 {
     decode_address(address_space(), addr_reg);
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-    if( !sh4_x86.tlb_on && (sh4<span id="removedchars" style="background-color:#ff9999;font-weight:bolder;" >r.xlat_</span>sh4_mode & SR_MD) ) { 
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+    if( !sh4_x86.tlb_on && (sh4<span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >_x86.</span>sh4_mode & SR_MD) ) { 
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >         CALL1_r32disp_r32(REG_ECX, offset, addr_reg);
     } else {
         if( addr_reg != REG_ARG1 ) {
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -393,7 +398,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > static void call_write_func(int addr_reg, int value_reg, int offset, int pc)
 {
     decode_address(address_space(), addr_reg);
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-    if( !sh4_x86.tlb_on && (sh4<span id="removedchars" style="background-color:#ff9999;font-weight:bolder;" >r.xlat_</span>sh4_mode & SR_MD) ) { 
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+    if( !sh4_x86.tlb_on && (sh4<span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >_x86.</span>sh4_mode & SR_MD) ) { 
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >         CALL2_r32disp_r32_r32(REG_ECX, offset, addr_reg, value_reg);
     } else {
         if( value_reg != REG_ARG2 ) {
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -444,8 +449,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > 
 void sh4_translate_begin_block( sh4addr_t pc ) 
 {
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-    enter_block();
-    MOVP_immptr_rptr( ((uint8_t *)&sh4r) + 128, REG_EBP );
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+     sh4_x86.code = xlat_output;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     sh4_x86.in_delay_slot = FALSE;
     sh4_x86.fpuen_checked = FALSE;
     sh4_x86.branch_taken = FALSE;
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -455,6 +459,8 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     sh4_x86.tstate = TSTATE_NONE;
     sh4_x86.double_prec = sh4r.fpscr & FPSCR_PR;
     sh4_x86.double_size = sh4r.fpscr & FPSCR_SZ;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+    sh4_x86.sh4_mode = sh4r.xlat_sh4_mode;
+    enter_block();
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
 
 
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -481,19 +487,49 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > 
 #define UNTRANSLATABLE(pc) !IS_IN_ICACHE(pc)
 
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+/** Offset of xlat_sh4_mode field relative to the code pointer */ 
+#define XLAT_SH4_MODE_CODE_OFFSET  (uint32_t)(offsetof(struct xlat_cache_block, xlat_sh4_mode) - offsetof(struct xlat_cache_block,code) )
+
+/**
+ * Test if the loaded target code pointer in %eax is valid, and if so jump
+ * directly into it, bypassing the normal exit.
+ */
+static void jump_next_block()
+{
+       TESTP_rptr_rptr(REG_EAX, REG_EAX);
+       JE_label(nocode);
+       if( sh4_x86.sh4_mode == SH4_MODE_UNKNOWN ) {
+           /* sr/fpscr was changed, possibly updated xlat_sh4_mode, so reload it */
+           MOVL_rbpdisp_r32( REG_OFFSET(xlat_sh4_mode), REG_ECX );
+           CMPL_r32_r32disp( REG_ECX, REG_EAX, XLAT_SH4_MODE_CODE_OFFSET );
+       } else {
+           CMPL_imms_r32disp( sh4_x86.sh4_mode, REG_EAX, XLAT_SH4_MODE_CODE_OFFSET );
+       }
+       JNE_label(wrongmode);
+       LEAP_rptrdisp_rptr(REG_EAX, PROLOGUE_SIZE,REG_EAX);
+       JMP_rptr(REG_EAX);
+       JMP_TARGET(nocode); JMP_TARGET(wrongmode);
+}
+
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > /**
  * Exit the block with sh4r.pc already written
  */
 void exit_block_pcset( sh4addr_t pc )
 {
     MOVL_imm32_r32( ((pc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period, REG_ECX );
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-    ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) );
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+    ADDL_rbpdisp_r32( REG_OFFSET(slice_cycle), REG_ECX );
+    MOVL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) );
+    CMPL_r32_rbpdisp( REG_ECX, REG_OFFSET(event_pending) );
+    JBE_label(exitloop);
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     MOVL_rbpdisp_r32( R_PC, REG_ARG1 );
     if( sh4_x86.tlb_on ) {
         CALL1_ptr_r32(xlat_get_code_by_vma,REG_ARG1);
     } else {
         CALL1_ptr_r32(xlat_get_code,REG_ARG1);
     }
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+    
+    jump_next_block();
+    JMP_TARGET(exitloop);
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     exit_block();
 }
 
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -503,14 +539,20 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > void exit_block_newpcset( sh4addr_t pc )
 {
     MOVL_imm32_r32( ((pc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period, REG_ECX );
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-    ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) );
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+    ADDL_rbpdisp_r32( REG_OFFSET(slice_cycle), REG_ECX );
+    MOVL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) );
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     MOVL_rbpdisp_r32( R_NEW_PC, REG_ARG1 );
     MOVL_r32_rbpdisp( REG_ARG1, R_PC );
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+    CMPL_r32_rbpdisp( REG_ECX, REG_OFFSET(event_pending) );
+    JBE_label(exitloop);
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     if( sh4_x86.tlb_on ) {
         CALL1_ptr_r32(xlat_get_code_by_vma,REG_ARG1);
     } else {
         CALL1_ptr_r32(xlat_get_code,REG_ARG1);
     }
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+     
+       jump_next_block();
+    JMP_TARGET(exitloop);
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     exit_block();
 }
 
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -520,18 +562,25 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >  */
 void exit_block_abs( sh4addr_t pc, sh4addr_t endpc )
 {
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-    MOVL_imm32_r32( pc, REG_ECX );
-    MOVL_r32_rbpdisp( REG_ECX, R_PC );
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+    MOVL_imm32_r32( ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period, REG_ECX );
+    ADDL_rbpdisp_r32( REG_OFFSET(slice_cycle), REG_ECX );
+    MOVL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) );
+
+    MOVL_imm32_r32( pc, REG_ARG1 );
+    MOVL_r32_rbpdisp( REG_ARG1, R_PC );
+    CMPL_r32_rbpdisp( REG_ECX, REG_OFFSET(event_pending) );
+    JBE_label(exitloop);
+
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     if( IS_IN_ICACHE(pc) ) {
         MOVP_moffptr_rax( xlat_get_lut_entry(GET_ICACHE_PHYS(pc)) );
         ANDP_imms_rptr( -4, REG_EAX );
     } else if( sh4_x86.tlb_on ) {
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-        CALL1_ptr_r32(xlat_get_code_by_vma, REG_<span id="removedchars" style="background-color:#ff9999;font-weight:bolder;" >ECX</span>);
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+        CALL1_ptr_r32(xlat_get_code_by_vma, REG_<span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >ARG1</span>);
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     } else {
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-        CALL1_ptr_r32(xlat_get_code, REG_<span id="removedchars" style="background-color:#ff9999;font-weight:bolder;" >ECX</span>);
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+        CALL1_ptr_r32(xlat_get_code, REG_<span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >ARG1</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;" >-    MOVL_imm32_r32( ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period, REG_ECX );
-    ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) );
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+    jump_next_block();
+    JMP_TARGET(exitloop);
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     exit_block();
 }
 
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -540,19 +589,36 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >  */
 void exit_block_rel( sh4addr_t pc, sh4addr_t endpc )
 {
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-    MOVL_imm32_r32( pc - sh4_x86.block_start_pc, REG_ECX );
-    ADDL_rbpdisp_r32( R_PC, REG_ECX );
-    MOVL_r32_rbpdisp( REG_ECX, R_PC );
-    if( IS_IN_ICACHE(pc) ) {
-        MOVP_moffptr_rax( xlat_get_lut_entry(GET_ICACHE_PHYS(pc)) );
-        ANDP_imms_rptr( -4, REG_EAX );
-    } else if( sh4_x86.tlb_on ) {
-        CALL1_ptr_r32(xlat_get_code_by_vma, REG_ECX);
-    } else {
-        CALL1_ptr_r32(xlat_get_code, REG_ECX);
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+    MOVL_imm32_r32( ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period, REG_ECX );
+    ADDL_rbpdisp_r32( REG_OFFSET(slice_cycle), REG_ECX );
+    MOVL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) );
+
+       if( pc == sh4_x86.block_start_pc && sh4_x86.sh4_mode == sh4r.xlat_sh4_mode ) {
+           /* Special case for tight loops - the PC doesn't change, and
+            * we already know the target address. Just check events pending before
+            * looping.
+            */
+        CMPL_r32_rbpdisp( REG_ECX, REG_OFFSET(event_pending) );
+        uint32_t backdisp = ((uintptr_t)(sh4_x86.code - xlat_output)) + PROLOGUE_SIZE;
+        JCC_cc_prerel(X86_COND_A, backdisp);
+       } else {
+        MOVL_imm32_r32( pc - sh4_x86.block_start_pc, REG_ARG1 );
+        ADDL_rbpdisp_r32( R_PC, REG_ARG1 );
+        MOVL_r32_rbpdisp( REG_ARG1, R_PC );
+        CMPL_r32_rbpdisp( REG_ECX, REG_OFFSET(event_pending) );
+        JBE_label(exitloop2);
+
+        if( IS_IN_ICACHE(pc) ) {
+            MOVP_moffptr_rax( xlat_get_lut_entry(GET_ICACHE_PHYS(pc)) );
+            ANDP_imms_rptr( -4, REG_EAX );
+        } else if( sh4_x86.tlb_on ) {
+            CALL1_ptr_r32(xlat_get_code_by_vma, REG_ARG1);
+        } else {
+            CALL1_ptr_r32(xlat_get_code, REG_ARG1);
+        }
+        jump_next_block();
+        JMP_TARGET(exitloop2);
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     }
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-    MOVL_imm32_r32( ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period, REG_ECX );
-    ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) );
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     exit_block();
 }
 
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -567,13 +633,6 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) );
     MOVL_imm32_r32( code, REG_ARG1 );
     CALL1_ptr_r32( sh4_raise_exception, REG_ARG1 );
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-    MOVL_rbpdisp_r32( R_PC, REG_ARG1 );
-    if( sh4_x86.tlb_on ) {
-        CALL1_ptr_r32(xlat_get_code_by_vma,REG_ARG1);
-    } else {
-        CALL1_ptr_r32(xlat_get_code,REG_ARG1);
-    }
-
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     exit_block();
 }    
 
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -599,13 +658,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     MOVL_imm32_r32( sh4_x86.in_delay_slot ? 1 : 0, REG_ECX );
     MOVL_r32_rbpdisp( REG_ECX, REG_OFFSET(in_delay_slot) );
 
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-    CALL_ptr( sh4_execute_instruction );    
-    MOVL_rbpdisp_r32( R_PC, REG_EAX );
-    if( sh4_x86.tlb_on ) {
-       CALL1_ptr_r32(xlat_get_code_by_vma,REG_EAX);
-    } else {
-       CALL1_ptr_r32(xlat_get_code,REG_EAX);
-    }
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+    CALL_ptr( sh4_execute_instruction );
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     exit_block();
 } 
 
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -627,12 +680,6 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >         MOVL_moffptr_eax( &sh4_cpu_period );
         MULL_r32( REG_EDX );
         ADDL_r32_rbpdisp( REG_EAX, REG_OFFSET(slice_cycle) );
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-        MOVL_rbpdisp_r32( R_PC, REG_ARG1 );
-        if( sh4_x86.tlb_on ) {
-            CALL1_ptr_r32(xlat_get_code_by_vma, REG_ARG1);
-        } else {
-            CALL1_ptr_r32(xlat_get_code, REG_ARG1);
-        }
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >         exit_block();
 
         for( i=0; i< sh4_x86.backpatch_posn; i++ ) {
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -1975,6 +2022,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >      sh4_x86.fpuen_checked = FALSE;
        sh4_x86.tstate = TSTATE_NONE;
        sh4_x86.branch_taken = TRUE;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+    sh4_x86.sh4_mode = SH4_MODE_UNKNOWN;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >    if( UNTRANSLATABLE(pc+2) ) {
            exit_block_emu(pc+2);
            return 2;
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -2539,6 +2587,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     XORL_imms_rbpdisp( FPSCR_SZ, REG_OFFSET(xlat_sh4_mode) );
     sh4_x86.tstate = TSTATE_NONE;
     sh4_x86.double_size = !sh4_x86.double_size;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+    sh4_x86.sh4_mode = sh4_x86.sh4_mode ^ FPSCR_SZ;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > :}
 
 /* Processor control instructions */
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -2552,6 +2601,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >      CALL1_ptr_r32( sh4_write_sr, REG_EAX );
        sh4_x86.fpuen_checked = FALSE;
        sh4_x86.tstate = TSTATE_NONE;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+    sh4_x86.sh4_mode = SH4_MODE_UNKNOWN;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >    return 2;
     }
 :}
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -2624,6 +2674,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >      CALL1_ptr_r32( sh4_write_sr, REG_EAX );
        sh4_x86.fpuen_checked = FALSE;
        sh4_x86.tstate = TSTATE_NONE;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+    sh4_x86.sh4_mode = SH4_MODE_UNKNOWN;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >    return 2;
     }
 :}
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -2693,6 +2744,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     load_reg( REG_EAX, Rm );
     CALL1_ptr_r32( sh4_write_fpscr, REG_EAX );
     sh4_x86.tstate = TSTATE_NONE;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+    sh4_x86.sh4_mode = SH4_MODE_UNKNOWN;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     return 2;
 :}
 LDS.L @Rm+, FPSCR {:  
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -2704,6 +2756,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );
     CALL1_ptr_r32( sh4_write_fpscr, REG_EAX );
     sh4_x86.tstate = TSTATE_NONE;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+    sh4_x86.sh4_mode = SH4_MODE_UNKNOWN;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     return 2;
 :}
 LDS Rm, FPUL {:  
</pre></div>
<hr /><a name="file5" /><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/test</span><br />
<div class="fileheader" style="margin-bottom:.5em;" ><big><b>testsh4x86.c</b></big> <small id="info" style="color: #888888;" >742c073f353f -> 4cac5e474d4c</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/src/test/testsh4x86.c
+++ lxdream/src/test/testsh4x86.c
@@ -113,6 +113,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > gboolean gui_error_dialog( const char *fmt, ... ) { return TRUE; }
 gboolean FASTCALL mmu_update_icache( sh4vma_t addr ) { return TRUE; }
 void MMU_ldtlb() { }
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+void event_schedule(int event, uint32_t nanos) { }
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > struct sh4_icache_struct sh4_icache;
 struct mem_region_fn mem_region_unmapped;
 const struct cpu_desc_struct sh4_cpu_desc;
</pre></div>
<hr /><a name="file6" /><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/xlat/x86</span><br />
<div class="fileheader" style="margin-bottom:.5em;" ><big><b>amd64abi.h</b></big> <small id="info" style="color: #888888;" >742c073f353f -> 4cac5e474d4c</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/src/xlat/x86/amd64abi.h
+++ lxdream/src/xlat/x86/amd64abi.h
@@ -94,6 +94,8 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     CALL_r32disp(preg, disp);    
 }
 
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+#define PROLOGUE_SIZE 15
+
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > /**
  * Emit the 'start of block' assembly. Sets up the stack frame and save
  * SI/DI as required
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -102,6 +104,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > {
     PUSH_r32(REG_RBP);
     SUBQ_imms_r64( 16, REG_RSP ); 
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+    MOVP_immptr_rptr( ((uint8_t *)&sh4r) + 128, REG_EBP );
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
 
 static inline void exit_block( )
</pre></div>
<hr /><a name="file7" /><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/xlat/x86</span><br />
<div class="fileheader" style="margin-bottom:.5em;" ><big><b>ia32abi.h</b></big> <small id="info" style="color: #888888;" >742c073f353f -> 4cac5e474d4c</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/src/xlat/x86/ia32abi.h
+++ lxdream/src/xlat/x86/ia32abi.h
@@ -132,6 +132,8 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > 
 #endif
 
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+#define PROLOGUE_SIZE 9
+
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > /**
  * Emit the 'start of block' assembly. Sets up the stack frame and save
  * SI/DI as required
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -142,6 +144,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > {
     PUSH_r32(REG_EBP);
     SUBL_imms_r32( 8, REG_ESP ); 
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+    MOVP_immptr_rptr( ((uint8_t *)&sh4r) + 128, REG_EBP );
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
 
 static inline void exit_block( )
</pre></div>
<hr /><a name="file8" /><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/xlat/x86</span><br />
<div class="fileheader" style="margin-bottom:.5em;" ><big><b>x86op.h</b></big> <small id="info" style="color: #888888;" >742c073f353f -> 4cac5e474d4c</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/src/xlat/x86/x86op.h
+++ lxdream/src/xlat/x86/x86op.h
@@ -314,6 +314,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > #define x86_encode_opcode32(opcode,reg) x86_encode_opcodereg(0,opcode,reg)
 #define x86_encode_r32_rm32(opcode,rr,rb) x86_encode_reg_rm(0,opcode,rr,rb)
 #define x86_encode_r64_rm64(opcode,rr,rb) x86_encode_reg_rm(PREF_REXW,opcode,rr,rb)
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+#define x86_encode_rptr_rmptr(opcode,rr,rb) x86_encode_reg_rm(PREF_PTR,opcode,rr,rb)
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > #define x86_encode_r32_mem32(opcode,rr,rb,rx,ss,disp32) x86_encode_modrm(0,opcode,rr,rb,rx,ss,disp32)
 #define x86_encode_r64_mem64(opcode,rr,rb,rx,ss,disp32) x86_encode_modrm(PREF_REXW,opcode,rr,rb,rx,ss,disp32)
 #define x86_encode_rptr_memptr(opcode,rr,rb,rx,ss,disp32) x86_encode_modrm(PREF_PTR,opcode,rr,rb,rx,ss,disp32)
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -397,8 +398,10 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > #define CMPB_imms_rbpdisp(imm,disp)  x86_encode_r32_rbpdisp32(0x80, 7, disp); OP(imm)
 #define CMPB_r8_r8(r1,r2)            x86_encode_r32_rm32(0x38, r1, r2)
 #define CMPL_imms_r32(imm,r1)        x86_encode_imms_rm32(0x83, 0x81, 7, imm, r1)
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+#define CMPL_imms_r32disp(imm,rb,d)  x86_encode_imms_r32disp32(0x83, 0x81, 7, imm, rb, d)
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > #define CMPL_imms_rbpdisp(imm,disp)  x86_encode_imms_rbpdisp32(0x83, 0x81, 7, imm, disp)
 #define CMPL_r32_r32(r1,r2)          x86_encode_r32_rm32(0x39, r1, r2)
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+#define CMPL_r32_r32disp(r1,r2,dsp)  x86_encode_r32_mem32disp32(0x39, r1, r2, dsp)
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > #define CMPL_r32_rbpdisp(r1,disp)    x86_encode_r32_rbpdisp32(0x39, r1, disp)
 #define CMPL_rbpdisp_r32(disp,r1)    x86_encode_r32_rbpdisp32(0x3B, r1, disp)
 #define CMPQ_imms_r64(imm,r1)        x86_encode_imms_rm64(0x83, 0x81, 7, imm, r1)
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -423,7 +426,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > #define LEAL_sib_r32(ss,ii,bb,d,r1)  x86_encode_r32_mem32(0x8D, r1, bb, ii, ss, d)
 #define LEAQ_r64disp_r64(r1,disp,r2) x86_encode_r64_mem64(0x8D, r2, r1, -1, 0, disp)
 #define LEAQ_rbpdisp_r64(disp,r1)    x86_encode_r64_rbpdisp64(0x8D, r1, disp)
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-#define LEAP_rptrdisp_rptr(r1,d,r2)  x86_encode_rptr_memptr(0x8D, r2, r1, -1, 0, d<span id="removedchars" style="background-color:#ff9999;font-weight:bolder;" >isp</span>)
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+#define LEAP_rptrdisp_rptr(r1,d,r2)  x86_encode_rptr_memptr(0x8D, r2, r1, -1, 0, d)
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > #define LEAP_rbpdisp_rptr(disp,r1)   x86_encode_rptr_memptr(0x8D, r1, REG_RBP, -1, 0, disp)
 #define LEAP_sib_rptr(ss,ii,bb,d,r1) x86_encode_rptr_memptr(0x8D, r1, bb, ii, ss, d)
 
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -562,6 +565,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > #define TESTL_rbpdisp_r32(disp,r1)   x86_encode_r32_rbpdisp32(0x85, r1, disp) /* Same OP */
 #define TESTQ_imms_r64(imm,r1)       x86_encode_r64_rm64(0xF7, 0, r1); OP32(imm)
 #define TESTQ_r64_r64(r1,r2)         x86_encode_r64_rm64(0x85, r1, r2)
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+#define TESTP_rptr_rptr(r1,r2)       x86_encode_rptr_rmptr(0x85, r1, r2)
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > 
 #define XCHGB_r8_r8(r1,r2)           x86_encode_r32_rm32(0x86, r1, r2)
 #define XCHGL_r32_r32(r1,r2)         x86_encode_r32_rm32(0x87, r1, r2)
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -586,12 +590,13 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > #define JCC_cc_rel8(cc,rel)          OP(0x70+(cc)); OP(rel)
 #define JCC_cc_rel32(cc,rel)         OP(0x0F); OP(0x80+(cc)); OP32(rel)
 #define JCC_cc_rel(cc,rel)           if( IS_INT8(rel) ) { JCC_cc_rel8(cc,(int8_t)rel); } else { JCC_cc_rel32(cc,rel); }
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+#define JCC_cc_prerel(cc,rel)        if( IS_INT8(rel) ) { JCC_cc_rel8(cc,(int8_t)((rel)-2)); } else { JCC_cc_rel32(cc,((rel)-6)); }
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > 
 #define JMP_rel8(rel)                OP(0xEB); OP(rel)
 #define JMP_rel32(rel)               OP(0xE9); OP32(rel)
 #define JMP_rel(rel)                 if( IS_INT8(rel) ) { JMP_rel8((int8_t)rel); } else { JMP_rel32(rel); }
 #define JMP_prerel(rel)              if( IS_INT8(((int32_t)rel)-2) ) { JMP_rel8(((int8_t)rel)-2); } else { JMP_rel32(((int32_t)rel)-5); }
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-#define JMP_r<span id="removedchars" style="background-color:#ff9999;font-weight:bolder;" >32(r1,disp)</span>             x86_encode_r32_rm32(0xFF, 4, r1)
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+#define JMP_r<span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >ptr(r1)    </span>             x86_encode_r32_rm32(0xFF, 4, r1)
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > #define JMP_r32disp(r1,disp)         x86_encode_r32_mem32disp32(0xFF, 4, r1, disp)
 #define RET()                        OP(0xC3)
 #define RET_imm(imm)                 OP(0xC2); OP16(imm)
</pre></div>
<center><small>Chaos Theory</small></center>
</div></body></html>