diff options
| author | Yang Liu <numbksco@gmail.com> | 2024-06-01 23:14:23 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-06-01 17:14:23 +0200 |
| commit | 9dbd7fc7e0615f48c9287305610bf9aed1cc24f3 (patch) | |
| tree | 0a9cd649a22b32cf99a59810f77cba6c557f4075 | |
| parent | a79eff3b0da5056e2226b7830aa5089e68c91451 (diff) | |
| download | box64-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
| -rw-r--r-- | src/dynarec/la64/la64_lock.S | 3 | ||||
| -rw-r--r-- | src/dynarec/native_lock.h | 9 | ||||
| -rw-r--r-- | src/dynarec/rv64/rv64_lock.S | 11 | ||||
| -rw-r--r-- | src/emu/x64runf0.c | 43 |
4 files changed, 34 insertions, 32 deletions
diff --git a/src/dynarec/la64/la64_lock.S b/src/dynarec/la64/la64_lock.S index 48f21595..18736afd 100644 --- a/src/dynarec/la64/la64_lock.S +++ b/src/dynarec/la64/la64_lock.S @@ -191,9 +191,8 @@ la64_lock_cas_dd: la64_lock_cas_dq: ll.d $a4, $a0, 0 bne $a4, $a2, 1f - sc.d $a1, $a0, 0 + .word 0x38571c85 // sc.q $a1, $a3, $a0 beqz $a1, 1f - st.d $a3, $a0, 8 xori $a0, $a1, 1 ret 1: diff --git a/src/dynarec/native_lock.h b/src/dynarec/native_lock.h index 33626a63..1ed26e8f 100644 --- a/src/dynarec/native_lock.h +++ b/src/dynarec/native_lock.h @@ -66,13 +66,8 @@ #define native_lock_write_d(A, B) rv64_lock_cas_d(A, tmpcas, B) #define native_lock_read_dd(A) tmpcas=*(uint64_t*)(A) #define native_lock_write_dd(A, B) rv64_lock_cas_dd(A, tmpcas, B) -// there is no atomic move on 16bytes, so faking it -#define native_lock_read_dq(A, B, C) \ - do { \ - *A = tmpcas = ((uint64_t*)(C))[0]; \ - *B = ((uint64_t*)(C))[1]; \ - } while (0) -#define native_lock_write_dq(A, B, C) rv64_lock_cas_dq(C, A, tmpcas, B); +#define native_lock_read_dq(A, B, C) // never used +#define native_lock_write_dq(A, B, C) // never used #define native_lock_get_b(A) rv64_lock_get_b(A) #define native_lock_get_d(A) rv64_lock_get_d(A) #define native_lock_get_dd(A) rv64_lock_get_dd(A) diff --git a/src/dynarec/rv64/rv64_lock.S b/src/dynarec/rv64/rv64_lock.S index 2b48163b..a525c999 100644 --- a/src/dynarec/rv64/rv64_lock.S +++ b/src/dynarec/rv64/rv64_lock.S @@ -229,17 +229,6 @@ rv64_lock_cas_dd: li a0, 1 ret -rv64_lock_cas_dq: - mv a4, a0 - lr.d t0, (a0) - bne t0, a1, 1f - sc.d a0, a2, (a0) - sd a3,(a4) - ret -1: - li a0, 1 - ret - rv64_lock_get_b: fence rw, rw lb a0, 0(a0) 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 { |