about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-03-29 17:28:00 +0200
committerptitSeb <sebastien.chev@gmail.com>2021-03-29 17:28:00 +0200
commitac2f2516a2d6d011a35fe050391adbd5e691950f (patch)
treec6ddba3379b7816c105b6a747f3caa8678724aee /src
parent8994f9580c1cae44d30395baa6a272853bb05d30 (diff)
downloadbox64-ac2f2516a2d6d011a35fe050391adbd5e691950f.tar.gz
box64-ac2f2516a2d6d011a35fe050391adbd5e691950f.zip
[ARM64] Added a new arm64_lock_storeifref helper
Diffstat (limited to 'src')
-rwxr-xr-xsrc/dynarec/arm64_lock.S22
-rwxr-xr-xsrc/dynarec/arm64_lock.h3
2 files changed, 19 insertions, 6 deletions
diff --git a/src/dynarec/arm64_lock.S b/src/dynarec/arm64_lock.S
index 09a0eb9d..9f89b4e2 100755
--- a/src/dynarec/arm64_lock.S
+++ b/src/dynarec/arm64_lock.S
@@ -17,6 +17,7 @@
 .global arm64_lock_write_dq
 .global arm64_lock_xchg
 .global arm64_lock_storeifnull
+.global arm64_lock_storeifref
 
 
 arm64_lock_read_b:
@@ -85,20 +86,29 @@ arm64_lock_xchg:
     // address is x0, value is x1, return old value in x0
     ldaxr   x2, [x0]
     stlxr   w3, x1, [x0]
-    cmp     w3, #1
-    beq     arm64_lock_xchg
+    cbnz    w3, arm64_lock_xchg
     mov     x0, x2
     ret
 
 arm64_lock_storeifnull:
     // address is x0, value is x1, x1 store to x0 only if [x0] is 0. return new [x0] value (so x1 or old value)
     ldaxr   x2, [x0]
-    cmp     x2, #0
-    bne     arm64_lock_storeifnull_exit
+    cbnz    x2, arm64_lock_storeifnull_exit
     mov     x2, x1
     stlxr   w3, x2, [x0]
-    cmp     w3, #1
-    beq     arm64_lock_storeifnull
+    cbnz    w3, arm64_lock_storeifnull
 arm64_lock_storeifnull_exit:
     mov     x0, x2
     ret
+
+arm64_lock_storeifref:
+    // address is x0, value is x1, x1 store to x0 only if [x0] is x3. return new [x0] value (so x1 or old value)
+    ldaxr   x3, [x0]
+    cmp     x2, x3
+    bne     arm64_lock_storeifref_exit
+    mov     x2, x1
+    stlxr   w4, x2, [x0]
+    cbnz    w4, arm64_lock_storeifref
+arm64_lock_storeifref_exit:
+    mov     x0, x2
+    ret
diff --git a/src/dynarec/arm64_lock.h b/src/dynarec/arm64_lock.h
index dafdd188..8f6bd14d 100755
--- a/src/dynarec/arm64_lock.h
+++ b/src/dynarec/arm64_lock.h
@@ -33,4 +33,7 @@ extern uintptr_t arm64_lock_xchg(void* p, uintptr_t val);
 // Atomicaly store value to [p] only if [p] is NULL. Return new [p] value (so val or old)
 extern void* arm64_lock_storeifnull(void*p, void* val);
 
+// Atomicaly store value to [p] only if [p] is ref. Return new [p] value (so val or old)
+extern void* arm64_lock_storeifref(void*p, void* val, void* ref);
+
 #endif  //__ARM64_LOCK__H__
\ No newline at end of file