From 8018dde3ea6cb7bf0b3a3c3f08cd893511e92ca2 Mon Sep 17 00:00:00 2001 From: kbkpbot Date: Sat, 3 Jan 2026 14:28:38 +0800 Subject: [PATCH] thirdparty: fix tcc __atomic_thread_fence (fix #25856) (fix #26158) (#26185) --- .github/workflows/docker_ci.yml | 19 +++++ thirdparty/stdatomic/nix/atomic.S | 94 ++++++++++++++++++++++ thirdparty/stdatomic/nix/atomic.h | 11 ++- vlib/sync/stdatomic/1.declarations.c.v | 2 + vlib/v/builder/cc.v | 2 +- vlib/v/tests/tcc_arm64_atomic_fence_test.v | 16 ++++ 6 files changed, 142 insertions(+), 2 deletions(-) create mode 100644 thirdparty/stdatomic/nix/atomic.S create mode 100644 vlib/v/tests/tcc_arm64_atomic_fence_test.v diff --git a/.github/workflows/docker_ci.yml b/.github/workflows/docker_ci.yml index c8f2f11a2..82c11081f 100644 --- a/.github/workflows/docker_ci.yml +++ b/.github/workflows/docker_ci.yml @@ -53,6 +53,25 @@ jobs: - name: Run only essential tests run: VTEST_JUST_ESSENTIAL=1 ./v -silent test-self + docker-alpine-musl-tcc: + runs-on: ubuntu-24.04 + timeout-minutes: 241 + container: + image: thevlang/vlang:alpine-build + volumes: + - ${{github.workspace}}:/opt/vlang + steps: + - name: Checkout + uses: actions/checkout@v6 + - name: Add dependencies + run: apk add musl-dev libatomic_ops-dev libatomic openssl libc6-compat gcompat gc gc-dev binutils diffutils elfutils + - name: Build V + run: make + - name: Check if vpm compiles with tcc + run: ./v -show-c-output -showcc -no-retry-compilation -cc tcc cmd/tools/vpm + - name: Run only builtin and math tests + run: ./v test vlib/builtin + docker-ubuntu-musl: runs-on: ubuntu-24.04 timeout-minutes: 121 diff --git a/thirdparty/stdatomic/nix/atomic.S b/thirdparty/stdatomic/nix/atomic.S new file mode 100644 index 000000000..bab27a527 --- /dev/null +++ b/thirdparty/stdatomic/nix/atomic.S @@ -0,0 +1,94 @@ +/* ---------------------------------------------- */ +#if defined __i386__ + +#define endbr32 + + .text + + .global _V_atomic_thread_fence + .type _V_atomic_thread_fence, %function +_V_atomic_thread_fence: + endbr32 + lock orl $0x0,(%esp) + ret + +#endif //__i386__ + +/* ---------------------------------------------- */ +#if defined __x86_64__ && !defined _WIN32 +#define endbr64 + .text + .global __atomic_thread_fence + .type __atomic_thread_fence, %function +__atomic_thread_fence: + endbr64 + lock orq $0x0,(%rsp) + ret +#endif //__x86_64__ && !_WIN32 + +/* ---------------------------------------------- */ +#if defined __x86_64__ && defined _WIN32 + .text + + .global _V_atomic_thread_fence + .type _V_atomic_thread_fence, %function +_V_atomic_thread_fence: + lock orq $0x0,(%rsp) + ret + +#endif //__x86_64__ && _WIN32 + +/* ---------------------------------------------- */ +#if defined __arm__ + .text +#ifndef __TINYC__ + .arch armv6k + .syntax unified +#endif + + .global _V_atomic_thread_fence + .type _V_atomic_thread_fence, %function +_V_atomic_thread_fence: +#ifdef __TINYC__ + .int 0xee070fba + .int 0xe12fff1e +#else + mcr p15, #0, r0, c7, c10, #5 + bx lr + +#endif +#endif //__arm__ + +/* ---------------------------------------------- */ +#if defined __aarch64__ + .text + + .global _V_atomic_thread_fence + .type _V_atomic_thread_fence, %function +_V_atomic_thread_fence: +#ifdef __TINYC__ + .int 0xd5033bbf + .int 0xd65f03c0 +#else + dmb ish + ret + +#endif +#endif //__aarch64__ + +/* ---------------------------------------------- */ +#if defined __riscv + .text + + .global _V_atomic_thread_fence + .type _V_atomic_thread_fence, %function +_V_atomic_thread_fence: +#ifdef __TINYC__ + .int 0x0330000f + .short 0x8082 +#else + fence rw,rw + ret + +#endif +#endif //__riscv diff --git a/thirdparty/stdatomic/nix/atomic.h b/thirdparty/stdatomic/nix/atomic.h index 80b5a884e..f56b9dcde 100644 --- a/thirdparty/stdatomic/nix/atomic.h +++ b/thirdparty/stdatomic/nix/atomic.h @@ -53,7 +53,16 @@ typedef volatile uintptr_t atomic_uintptr_t; extern void atomic_thread_fence (int memory_order); extern void __atomic_thread_fence (int memory_order); -#define atomic_thread_fence(order) __atomic_thread_fence (order) + +// workaround for tcc/aarch64 +#if defined(__aarch64__) || defined(_M_ARM64) + // `_V_atomic_thread_fence` is defined in `atomic.S` + extern void _V_atomic_thread_fence(int memory_order); + #define atomic_thread_fence(order) _V_atomic_thread_fence(order) + #define __atomic_thread_fence(order) _V_atomic_thread_fence(order) +#else + #define atomic_thread_fence(order) __atomic_thread_fence(order) +#endif // use functions for 64, 32 and 8 bit from libatomic directly // since tcc is not capible to use "generic" C functions diff --git a/vlib/sync/stdatomic/1.declarations.c.v b/vlib/sync/stdatomic/1.declarations.c.v index 7ab3ddabb..6950c3ba1 100644 --- a/vlib/sync/stdatomic/1.declarations.c.v +++ b/vlib/sync/stdatomic/1.declarations.c.v @@ -25,6 +25,7 @@ $if linux { $if musl ? { // Alpine: #flag $when_first_existing('/usr/lib/libatomic.a','/usr/lib/gcc/x86_64-pc-linux-musl/6/libatomic.a','/usr/lib/gcc/x86_64-pc-linux-musl/7/libatomic.a','/usr/lib/gcc/x86_64-pc-linux-musl/8/libatomic.a','/usr/lib/gcc/x86_64-pc-linux-musl/9/libatomic.a','/usr/lib/gcc/x86_64-pc-linux-musl/10/libatomic.a','/usr/lib/gcc/x86_64-pc-linux-musl/11/libatomic.a','/usr/lib/gcc/x86_64-pc-linux-musl/12/libatomic.a','/usr/lib/gcc/x86_64-pc-linux-musl/13/libatomic.a','/usr/lib/gcc/x86_64-pc-linux-musl/14/libatomic.a') + #flag @VEXEROOT/thirdparty/stdatomic/nix/atomic.o } } $else $if arm64 { // Note: Use `.so` instead of `.a`. @@ -62,6 +63,7 @@ $if linux { // Alpine: #flag $when_first_existing('/usr/lib/libatomic.so','/usr/lib/gcc/aarch64-pc-linux-musl/6/libatomic.so','/usr/lib/gcc/aarch64-pc-linux-musl/7/libatomic.so','/usr/lib/gcc/aarch64-pc-linux-musl/8/libatomic.so','/usr/lib/gcc/aarch64-pc-linux-musl/9/libatomic.so','/usr/lib/gcc/aarch64-pc-linux-musl/10/libatomic.so','/usr/lib/gcc/aarch64-pc-linux-musl/11/libatomic.so','/usr/lib/gcc/aarch64-pc-linux-musl/12/libatomic.so','/usr/lib/gcc/aarch64-pc-linux-musl/13/libatomic.so','/usr/lib/gcc/aarch64-pc-linux-musl/14/libatomic.so') } + #flag @VEXEROOT/thirdparty/stdatomic/nix/atomic.o } } } diff --git a/vlib/v/builder/cc.v b/vlib/v/builder/cc.v index 3c364a5af..bceeae462 100644 --- a/vlib/v/builder/cc.v +++ b/vlib/v/builder/cc.v @@ -1225,7 +1225,7 @@ fn (mut v Builder) build_thirdparty_obj_file(mod string, path string, moduleflag os.chdir(v.pref.vroot) or {} cc_options := if source_kind == .asm { - '-o ${v.tcc_quoted_path(opath)} -c ${v.tcc_quoted_path(source_file)}' + '-o ${os.quoted_path(opath)} -c ${os.quoted_path(source_file)}' } else { mut all_options := []string{cap: 4} all_options << v.pref.third_party_option diff --git a/vlib/v/tests/tcc_arm64_atomic_fence_test.v b/vlib/v/tests/tcc_arm64_atomic_fence_test.v new file mode 100644 index 000000000..18f86d1f5 --- /dev/null +++ b/vlib/v/tests/tcc_arm64_atomic_fence_test.v @@ -0,0 +1,16 @@ +// vtest build: tinyc && arm64 +// vtest vflags: -cc tcc -no-retry-compilation +module main + +fn test_tcc_arm64_atomic_fence() { + a := 1 + + b := fn [a] () int { + println(a) + return a + } + + g := spawn b() + ret := g.wait() + println(ret) // 1 +} -- 2.39.5