tinycc-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Tinycc-devel] [PATCH 2/2] stdatomic: x86_64 implementation


From: Dmitry Selyutin
Subject: [Tinycc-devel] [PATCH 2/2] stdatomic: x86_64 implementation
Date: Thu, 11 Mar 2021 23:11:45 +0300

---
 lib/Makefile            |   2 +-
 lib/atomic-emu.h        |  15 +++++
 lib/atomic-x86_64-emu.c |  16 +++++
 lib/atomic-x86_64.S     | 129 ++++++++++++++++++++++++++++++++++++++++
 4 files changed, 161 insertions(+), 1 deletion(-)
 create mode 100644 lib/atomic-emu.h
 create mode 100644 lib/atomic-x86_64-emu.c
 create mode 100644 lib/atomic-x86_64.S

diff --git a/lib/Makefile b/lib/Makefile
index 9121d33..96b4ffb 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -43,7 +43,7 @@ $(X)BT_O += tcov.o
 DSO_O = dsohandle.o

 I386_O = libtcc1.o alloca86.o alloca86-bt.o $(BT_O)
-X86_64_O = libtcc1.o alloca86_64.o alloca86_64-bt.o $(BT_O)
+X86_64_O = libtcc1.o alloca86_64.o alloca86_64-bt.o $(BT_O)
atomic-x86_64.o atomic-x86_64-emu.o
 ARM_O = libtcc1.o armeabi.o alloca-arm.o armflush.o fetch_and_add_arm.o $(BT_O)
 ARM64_O = lib-arm64.o fetch_and_add_arm64.o $(BT_O)
 RISCV64_O = lib-arm64.o fetch_and_add_riscv64.o $(BT_O)
diff --git a/lib/atomic-emu.h b/lib/atomic-emu.h
new file mode 100644
index 0000000..d879ccb
--- /dev/null
+++ b/lib/atomic-emu.h
@@ -0,0 +1,15 @@
+#include <stdatomic.h>
+#include <stdint.h>
+
+#define ATOMIC_FETCH_OP(NAME, TYPE, MODE, OP) \
+    TYPE __atomic_fetch_##NAME##_##MODE(_Atomic(TYPE) *atom, TYPE
value, memory_order order) \
+    { \
+        TYPE xchg; \
+        TYPE cmp = atomic_load_explicit(atom, memory_order_relaxed); \
+        \
+        do { \
+            xchg = (cmp OP value); \
+        } while (!atomic_compare_exchange_strong_explicit(atom, &cmp,
xchg, order, order)); \
+        \
+        return cmp; \
+    }
diff --git a/lib/atomic-x86_64-emu.c b/lib/atomic-x86_64-emu.c
new file mode 100644
index 0000000..6b3084e
--- /dev/null
+++ b/lib/atomic-x86_64-emu.c
@@ -0,0 +1,16 @@
+#include "atomic-emu.h"
+
+ATOMIC_FETCH_OP(or, uint8_t, 1, |)
+ATOMIC_FETCH_OP(or, uint16_t, 2, |)
+ATOMIC_FETCH_OP(or, uint32_t, 4, |)
+ATOMIC_FETCH_OP(or, uint64_t, 8, |)
+
+ATOMIC_FETCH_OP(xor, uint8_t, 1, ^)
+ATOMIC_FETCH_OP(xor, uint16_t, 2, ^)
+ATOMIC_FETCH_OP(xor, uint32_t, 4, ^)
+ATOMIC_FETCH_OP(xor, uint64_t, 8, ^)
+
+ATOMIC_FETCH_OP(and, uint8_t, 1, &)
+ATOMIC_FETCH_OP(and, uint16_t, 2, &)
+ATOMIC_FETCH_OP(and, uint32_t, 4, &)
+ATOMIC_FETCH_OP(and, uint64_t, 8, &)
diff --git a/lib/atomic-x86_64.S b/lib/atomic-x86_64.S
new file mode 100644
index 0000000..2d5c967
--- /dev/null
+++ b/lib/atomic-x86_64.S
@@ -0,0 +1,129 @@
+.section .text
+
+/* atomic_store */
+.global __atomic_store_1
+.type __atomic_store_1, STT_FUNC
+__atomic_store_1:
+    movzbl %sil,%esi
+    movb %sil,(%rdi)
+    ret
+
+.global __atomic_store_2
+.type __atomic_store_2, STT_FUNC
+__atomic_store_2:
+    movzwl %si,%esi
+    movw %si,(%rdi)
+    ret
+
+.global __atomic_store_4
+.type __atomic_store_4, STT_FUNC
+__atomic_store_4:
+    movl %esi,(%rdi)
+    ret
+
+.global __atomic_store_8
+.type __atomic_store_8, STT_FUNC
+__atomic_store_8:
+    movq %rsi,(%rdi)
+    ret
+
+/* atomic_load */
+.global __atomic_load_1
+.type __atomic_load_1, STT_FUNC
+__atomic_load_1:
+    movzbl (%rdi),%eax
+    ret
+
+.global __atomic_load_2
+.type __atomic_load_2, STT_FUNC
+__atomic_load_2:
+    movzwl (%rdi),%eax
+    ret
+
+.global __atomic_load_4
+.type __atomic_load_4, STT_FUNC
+__atomic_load_4:
+    movl (%rdi),%eax
+    ret
+
+.global __atomic_load_8
+.type __atomic_load_8, STT_FUNC
+__atomic_load_8:
+    movq (%rdi),%rax
+    ret
+
+/* atomic_exchange */
+.global __atomic_exchange_1
+.type __atomic_exchange_1, STT_FUNC
+__atomic_exchange_1:
+    movzbl %sil,%eax
+    xchgb %al,(%rdi)
+    ret
+
+.global __atomic_exchange_2
+.type __atomic_exchange_2, STT_FUNC
+__atomic_exchange_2:
+    movzwl %si,%eax
+    xchgw %ax,(%rdi)
+    ret
+
+.global __atomic_exchange_4
+.type __atomic_exchange_4, STT_FUNC
+__atomic_exchange_4:
+    movl %esi,%eax
+    xchgl %eax,(%rdi)
+    ret
+
+.global __atomic_exchange_8
+.type __atomic_exchange_8, STT_FUNC
+__atomic_exchange_8:
+    movq %rsi,%rax
+    xchgq %rax,(%rdi)
+    ret
+
+/* atomic_compare_exchange */
+.global __atomic_compare_exchange_1
+.type __atomic_compare_exchange_1, STT_FUNC
+__atomic_compare_exchange_1:
+    movzbl (%rsi),%eax
+    movzbl %dl,%edx
+    lock cmpxchgb %dl,(%rdi)
+    sete %r8b
+    je 0f
+    movb %al,(%rsi)
+0:  movl %r8d,%eax
+    ret
+
+.global __atomic_compare_exchange_2
+.type __atomic_compare_exchange_2, STT_FUNC
+__atomic_compare_exchange_2:
+    movzwl (%rsi),%eax
+    movzwl %dx,%edx
+    lock cmpxchgw %dx,(%rdi)
+    sete %r8b
+    je 0f
+    movw %ax,(%rsi)
+0:  movl %r8d,%eax
+    ret
+
+.global __atomic_compare_exchange_4
+.type __atomic_compare_exchange_4, STT_FUNC
+__atomic_compare_exchange_4:
+    movl (%rsi),%eax
+    lock cmpxchgl %edx,(%rdi)
+    sete %r8b
+    je 0f
+    movl %eax,(%rsi)
+0:  movl %r8d,%eax
+    ret
+
+.global __atomic_compare_exchange_8
+.type __atomic_compare_exchange_8, STT_FUNC
+__atomic_compare_exchange_8:
+    movq (%rsi),%rax
+    lock cmpxchgq %rdx,(%rdi)
+    sete %r8b
+    je 0f
+    movq %rax,(%rsi)
+0:  movl %r8d,%eax
+    ret
--
2.30.1



reply via email to

[Prev in Thread] Current Thread [Next in Thread]