about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <seebastien.chev@gmail.com>2023-09-02 09:31:38 +0200
committerptitSeb <seebastien.chev@gmail.com>2023-09-02 09:31:38 +0200
commiteb1e607b935a1c90c0c9cf0b352d95423e42740d (patch)
treedb8e6836e4c506ff735b1b2920dea15c81930e50 /src
parent9d16aec99a7854597a9adb415a6ef34c5fc17a16 (diff)
downloadbox64-eb1e607b935a1c90c0c9cf0b352d95423e42740d.tar.gz
box64-eb1e607b935a1c90c0c9cf0b352d95423e42740d.zip
Correctly handle TF flags, with [DYNAREC] falling back to Interpretor when TF is on (should help #914)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_00.c6
-rw-r--r--src/dynarec/dynarec.c2
-rw-r--r--src/dynarec/rv64/dynarec_rv64_00_2.c6
-rw-r--r--src/emu/x64run.c25
4 files changed, 21 insertions, 18 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c
index 84cf7daa..f960dc83 100644
--- a/src/dynarec/arm64/dynarec_arm64_00.c
+++ b/src/dynarec/arm64/dynarec_arm64_00.c
@@ -1296,10 +1296,8 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             SET_DFNONE(x1);
             if(box64_wine) {    // should this be done all the time?
                 TBZ_NEXT(xFlags, F_TF);
-                MOV64x(x1, addr);
-                STORE_XEMU_CALL(x1);
-                CALL(native_singlestep, -1);
-                BFCw(xFlags, F_TF, 1);
+                // go to epilog, TF should trigger at end of next opcode, so using Interpretor only
+                jump_to_epilog(dyn, addr, 0, ninst);
             }
             break;
         case 0x9E:
diff --git a/src/dynarec/dynarec.c b/src/dynarec/dynarec.c
index bb6b3ba9..77ca980c 100644
--- a/src/dynarec/dynarec.c
+++ b/src/dynarec/dynarec.c
@@ -134,7 +134,7 @@ void DynaRun(x64emu_t* emu)
         else {
             int is32bits = (emu->segs[_CS]==0x23);
             dynablock_t* block = (skip)?NULL:DBGetBlock(emu, R_RIP, 1, is32bits);
-            if(!block || !block->block || !block->done) {
+            if(!block || !block->block || !block->done || ACCESS_FLAG(F_TF)) {
                 skip = 0;
                 // no block, of block doesn't have DynaRec content (yet, temp is not null)
                 // Use interpreter (should use single instruction step...)
diff --git a/src/dynarec/rv64/dynarec_rv64_00_2.c b/src/dynarec/rv64/dynarec_rv64_00_2.c
index 20333f96..0ceaf4e0 100644
--- a/src/dynarec/rv64/dynarec_rv64_00_2.c
+++ b/src/dynarec/rv64/dynarec_rv64_00_2.c
@@ -499,10 +499,8 @@ uintptr_t dynarec64_00_2(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
             if(box64_wine) {    // should this be done all the time?
                 ANDI(x1, xFlags, 1 << F_TF);
                 CBZ_NEXT(x1);
-                MOV64x(xRIP, addr);
-                STORE_XEMU_CALL();
-                CALL(native_singlestep, -1);
-                ANDI(xFlags, xFlags, ~(1 << F_TF));
+                // go to epilog, TF should trigger at end of next opcode, so using Interpretor only
+                jump_to_epilog(dyn, addr, 0, ninst);
             }
             break;
         case 0x9F:
diff --git a/src/emu/x64run.c b/src/emu/x64run.c
index 5e19d642..110721b9 100644
--- a/src/emu/x64run.c
+++ b/src/emu/x64run.c
@@ -874,15 +874,6 @@ x64emurun:
         case 0x9D:                      /* POPF */
             emu->eflags.x64 = (((rex.is32bits?Pop32(emu):Pop64(emu)) & 0x3F7FD7)/* & (0xffff-40)*/ ) | 0x2; // mask off res2 and res3 and on res1
             RESET_FLAGS(emu);
-            #ifndef TEST_INTERPRETER
-            if(ACCESS_FLAG(F_TF)) {
-                R_RIP = addr;
-                emit_signal(emu, SIGTRAP, (void*)addr, 1);
-                if(emu->quit) goto fini;
-                CLEAR_FLAG(F_TF);
-                STEP;
-            }
-            #endif
             break;
         case 0x9E:                      /* SAHF */
             CHECK_FLAGS(emu);
@@ -2009,11 +2000,27 @@ x64emurun:
             unimp = 1;
             goto fini;
         }
+#ifndef TEST_INTERPRETER
+        // check the TRACE flag before going to next
+        if(ACCESS_FLAG(F_TF)) {
+            R_RIP = addr;
+            emit_signal(emu, SIGTRAP, (void*)addr, 1);
+            if(emu->quit) goto fini;
+        }
+#endif
         R_RIP = addr;
     }
 
 
 fini:
+#ifndef TEST_INTERPRETER
+    // check the TRACE flag before going to out, in case it's a step by step scenario
+    if(!emu->quit && !emu->fork && !emu->uc_link && ACCESS_FLAG(F_TF)) {
+        R_RIP = addr;
+        emit_signal(emu, SIGTRAP, (void*)addr, 1);
+        if(emu->quit) goto fini;
+    }
+#endif
 if(emu->segs[_CS]!=0x33 && emu->segs[_CS]!=0x23) printf_log(LOG_NONE, "Warning, CS is not default value: 0x%x\n", emu->segs[_CS]);
 #ifndef TEST_INTERPRETER
     printf_log(LOG_DEBUG, "End of X86 run (%p), RIP=%p, Stack=%p, unimp=%d, emu->fork=%d, emu->uc_link=%p, emu->quit=%d\n", emu, (void*)R_RIP, (void*)R_RSP, unimp, emu->fork, emu->uc_link, emu->quit);