about summary refs log tree commit diff stats
path: root/src/dynarec/arm64_lock.S
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-03-20 16:49:02 +0100
committerptitSeb <sebastien.chev@gmail.com>2021-03-20 16:49:02 +0100
commitdfb1cd487616cdcee38488eb1f6f30b76942bc69 (patch)
tree806df99832feddc40b05a787f6a03658a1005e02 /src/dynarec/arm64_lock.S
parentc2c34ccba37109ffe7c8d5fbc39ce64f8769fa67 (diff)
downloadbox64-dfb1cd487616cdcee38488eb1f6f30b76942bc69.tar.gz
box64-dfb1cd487616cdcee38488eb1f6f30b76942bc69.zip
Renamed arm64_lock_helper to arm64_lock
Diffstat (limited to 'src/dynarec/arm64_lock.S')
-rwxr-xr-xsrc/dynarec/arm64_lock.S87
1 files changed, 87 insertions, 0 deletions
diff --git a/src/dynarec/arm64_lock.S b/src/dynarec/arm64_lock.S
new file mode 100755
index 00000000..ebe7f8ec
--- /dev/null
+++ b/src/dynarec/arm64_lock.S
@@ -0,0 +1,87 @@
+//arm lock helper
+//there is 2 part: read and write
+// write return 0 on success, 1 on fail (value has been changed)
+
+.text
+.align 4
+
+.global arm64_lock_read_b
+.global arm64_lock_write_b
+.global arm64_lock_read_h
+.global arm64_lock_write_h
+.global arm64_lock_read_d
+.global arm64_lock_write_d
+.global arm64_lock_read_dd
+.global arm64_lock_write_dd
+.global arm64_lock_xchg
+.global arm64_lock_storeifnull
+
+
+arm64_lock_read_b:
+    // address is x0, return is x0
+    ldaxrb  w0, [x0]
+    ret
+
+arm64_lock_write_b:
+    // address is x0, value is x1, return is x0
+    mov     x2, x0
+    stlxrb  w0, w1, [x2]
+    ret
+
+arm64_lock_read_h:
+    // address is x0, return is x0
+    ldaxrh  w0, [x0]
+    ret
+
+arm64_lock_write_h:
+    // address is x0, value is x1, return is x0
+    mov     x2, x0
+    stlxrh  w0, w1, [x2]
+    ret
+
+arm64_lock_read_d:
+    // address is x0, return is x0
+    #ldaxr   w0, [x0]
+    ldr     w0,[x0]
+    ret
+
+arm64_lock_write_d:
+    // address is x0, value is w1, return is x0
+    mov     x2, x0
+    #stlxr   w0, w1, [x2]
+    str     w1, [x2]
+    mov     w0, 0
+    ret
+
+arm64_lock_read_dd:
+    // address is x0, return is x0
+    ldaxr   x0, [x0]
+    ret
+
+arm64_lock_write_dd:
+    // address is x0, value is x1, return is x0
+    mov     x2, x0
+    stlxr   w0, x1, [x2]
+    ret
+
+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
+    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
+    mov     x2, x1
+    stlxr   w3, x2, [x0]
+    cmp     w3, #1
+    beq     arm64_lock_storeifnull
+arm64_lock_storeifnull_exit:
+    mov     x0, x2
+    ret