about summary refs log tree commit diff stats
path: root/src/emu
diff options
context:
space:
mode:
authorYang Liu <numbksco@gmail.com>2024-06-01 23:14:23 +0800
committerGitHub <noreply@github.com>2024-06-01 17:14:23 +0200
commit9dbd7fc7e0615f48c9287305610bf9aed1cc24f3 (patch)
tree0a9cd649a22b32cf99a59810f77cba6c557f4075 /src/emu
parenta79eff3b0da5056e2226b7830aa5089e68c91451 (diff)
downloadbox64-9dbd7fc7e0615f48c9287305610bf9aed1cc24f3.tar.gz
box64-9dbd7fc7e0615f48c9287305610bf9aed1cc24f3.zip
[INTERP] Rework on the 16b emulation for LA64 (#1547)
* [INTERP] Rework on the 16b emulation for LA64

* fix compiler issue
Diffstat (limited to 'src/emu')
-rw-r--r--src/emu/x64runf0.c43
1 files changed, 31 insertions, 12 deletions
diff --git a/src/emu/x64runf0.c b/src/emu/x64runf0.c
index ce7145fc..c44100c5 100644
--- a/src/emu/x64runf0.c
+++ b/src/emu/x64runf0.c
@@ -746,19 +746,38 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr)
 #if defined(DYNAREC) && !defined(TEST_INTERPRETER)

                             if (rex.w) {

 #if defined(__riscv) || defined(__loongarch64)

-                                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;

+#if defined(__loongarch64)

+                                if (la64_scq) {

+                                    do {

+                                        native_lock_read_dq(&tmp64u, &tmp64u2, ED);

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

+                                            SET_FLAG(F_ZF);

+                                            tmp32s = native_lock_write_dq(R_RBX, R_RCX, ED);

+                                        } else {

+                                            CLEAR_FLAG(F_ZF);

+                                            R_RAX = tmp64u;

+                                            R_RDX = tmp64u2;

+                                            tmp32s = 0;

+                                        }

+                                    } while (tmp32s);

+                                } else

+#endif

+                                {

+                                    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

                                 }

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

 #else

                                 if(((uintptr_t)ED)&0xf) {

                                     do {