about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-11-23 13:06:26 +0100
committerptitSeb <sebastien.chev@gmail.com>2024-11-23 13:06:26 +0100
commit327dc2c835673d670429c95d6f5c18f5314375c9 (patch)
tree83ddd7239f94a83d962b0a412dce9e31219b9773 /src
parent8f937788ce7f8daee891052f17bc975eb19255e2 (diff)
downloadbox64-327dc2c835673d670429c95d6f5c18f5314375c9.tar.gz
box64-327dc2c835673d670429c95d6f5c18f5314375c9.zip
[DYNAREC] Better detection of wait slot
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/dynarec_native.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/src/dynarec/dynarec_native.c b/src/dynarec/dynarec_native.c
index e42b98f2..20ef8795 100644
--- a/src/dynarec/dynarec_native.c
+++ b/src/dynarec/dynarec_native.c
@@ -121,6 +121,8 @@ int is_nops(dynarec_native_t *dyn, uintptr_t addr, int n)
         return is_nops(dyn, addr+1, n-1);
     if(n>1 && PK(0)==0x66)  // if opcode start with 0x66, and there is more after, than is *can* be a NOP
         return is_nops(dyn, addr+1, n-1);
+    if(n>1 && PK(0)==0xF3 && PK(1)==0x90)
+        return is_nops(dyn, addr+2, n-2);
     if(n>2 && PK(0)==0x0f && PK(1)==0x1f && PK(2)==0x00)
         return is_nops(dyn, addr+3, n-3);
     if(n>2 && PK(0)==0x8d && PK(1)==0x76 && PK(2)==0x00)    // lea esi, [esi]
@@ -229,6 +231,14 @@ int next_instruction(dynarec_native_t *dyn, uintptr_t addr)
         case 0xBE:
         case 0xBF:
             return 5;
+        case 0xF3:
+            nextop = PK(1);
+            switch(nextop) {
+                case 0x90: 
+                    return 2;
+                default: break;
+            }
+            break;
         case 0xFF:
             nextop = PK(1);
             switch((nextop>>3)&7) {
@@ -642,6 +652,11 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr, int alternate, int is32bit
             if(k!=-1) {
                 if(!helper.insts[i].barrier_maybe)
                     helper.insts[k].x64.barrier |= BARRIER_FULL;
+                // special case, loop on itself with some nop in between
+                if(k<i && !helper.insts[i].x64.has_next && is_nops(&helper, helper.insts[k].x64.addr, helper.insts[i].x64.addr-helper.insts[k].x64.addr)) {
+                    helper.always_test = 1;
+                    k = -1;
+                }
                 helper.insts[i].x64.jmp_insts = k;
             }
         }