[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
- [Tinycc-devel] [PATCH 2/2] stdatomic: x86_64 implementation,
Dmitry Selyutin <=