about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2024-02-27 17:29:55 +0800
committerGitHub <noreply@github.com>2024-02-27 10:29:55 +0100
commite9ce6a4f80a1b82e5e8fcfac5951f1684df2836d (patch)
treecfe6b6372f6b6539c201ef99a1b0fb5ed0fa0e42
parent0024e4b970169137f6360ccb76776e97f1667e93 (diff)
downloadbox64-e9ce6a4f80a1b82e5e8fcfac5951f1684df2836d.tar.gz
box64-e9ce6a4f80a1b82e5e8fcfac5951f1684df2836d.zip
[RV64_INTERP] Comply CMPXCHG16B with dynarec (#1288)
-rw-r--r--src/emu/x64runf0.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/src/emu/x64runf0.c b/src/emu/x64runf0.c
index 20552e2e..e62237a0 100644
--- a/src/emu/x64runf0.c
+++ b/src/emu/x64runf0.c
@@ -744,7 +744,22 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr)
                             CHECK_FLAGS(emu);

                             GETGD;

 #if defined(DYNAREC) && !defined(TEST_INTERPRETER)

-                            if(rex.w)

+                            if (rex.w) {

+#if defined(__riscv)

+                                while (native_lock_xchg_d(&emu->context->mutex_16b, 1)); // lock

+                                tmp64u = ((uint64_t*)ED)[0];

+                                tmp64u2 = ((uint64_t*)ED)[1];

+                                if(R_RAX == tmp64u && R_RDX == tmp64u2) {

+                                    SET_FLAG(F_ZF);

+                                    ((uint64_t*)ED)[0] = R_RBX;

+                                    ((uint64_t*)ED)[1] = R_RCX;

+                                } else {

+                                    CLEAR_FLAG(F_ZF);

+                                    R_RAX = tmp64u;

+                                    R_RDX = tmp64u2;

+                                }

+                                native_lock_xchg_d(&emu->context->mutex_16b, 0); // unlock

+#else

                                 do {

                                     native_lock_read_dq(&tmp64u, &tmp64u2, ED);

                                     if(R_RAX == tmp64u && R_RDX == tmp64u2) {

@@ -757,7 +772,8 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr)
                                         tmp32s = 0;

                                     }

                                 } while(tmp32s);

-                            else

+#endif

+                            } else

                                 do {

                                     tmp64u = native_lock_read_dd(ED);

                                     if((R_EAX == (tmp64u&0xffffffff)) && (R_EDX == ((tmp64u>>32)&0xffffffff))) {