Skip to content

Commit 904e95c

Browse files
committed
win32: avoid Interlocked imports for tcc arm64
Windows/arm64 exposes Interlocked* operations as compiler intrinsics rather than kernel32 exports. When tcc -run self-compiles tcc.c, calls to InterlockedCompareExchange or InterlockedExchange can therefore remain as unresolved imports in the in-memory linker. Route the TinyCC arm64 path through the existing __atomic helpers while keeping Interlocked* for other Windows compilers. The compile-lock initialization state machine remains unchanged.
1 parent 601a088 commit 904e95c

1 file changed

Lines changed: 37 additions & 3 deletions

File tree

tcc.h

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1930,12 +1930,46 @@ dwarf_read_sleb128(unsigned char **ln, unsigned char *end)
19301930
#if CONFIG_TCC_SEMLOCK
19311931
#if defined _WIN32
19321932
typedef struct { volatile LONG init; CRITICAL_SECTION cs; } TCCSem;
1933+
#if defined __TINYC__ && (defined __aarch64__ || defined __arm64__)
1934+
/* Windows/arm64 Interlocked* names are compiler intrinsics, not
1935+
kernel32 exports, so tcc -run must not emit calls to them. */
1936+
# define TCC_SEM_USE_ATOMICS 1
1937+
enum { TCC_SEM_ATOMIC_SEQ_CST = 5 };
1938+
#endif
1939+
static inline LONG tcc_sem_cmpxchg(volatile LONG *ptr, LONG val, LONG cmp) {
1940+
#ifdef TCC_SEM_USE_ATOMICS
1941+
LONG old = cmp;
1942+
__atomic_compare_exchange((LONG *)ptr, &old, &val, 0,
1943+
TCC_SEM_ATOMIC_SEQ_CST,
1944+
TCC_SEM_ATOMIC_SEQ_CST);
1945+
return old;
1946+
#else
1947+
return InterlockedCompareExchange(ptr, val, cmp);
1948+
#endif
1949+
}
1950+
static inline void tcc_sem_store(volatile LONG *ptr, LONG val) {
1951+
#ifdef TCC_SEM_USE_ATOMICS
1952+
__atomic_store((LONG *)ptr, &val, TCC_SEM_ATOMIC_SEQ_CST);
1953+
#else
1954+
InterlockedExchange(ptr, val);
1955+
#endif
1956+
}
1957+
static inline LONG tcc_sem_load(volatile LONG *ptr) {
1958+
#ifdef TCC_SEM_USE_ATOMICS
1959+
LONG val;
1960+
__atomic_load((LONG *)ptr, &val, TCC_SEM_ATOMIC_SEQ_CST);
1961+
return val;
1962+
#else
1963+
return InterlockedCompareExchange(ptr, 0, 0);
1964+
#endif
1965+
}
19331966
static inline void wait_sem(TCCSem *p) {
1934-
if (InterlockedCompareExchange(&p->init, 1, 0) == 0) {
1967+
if (tcc_sem_cmpxchg(&p->init, 1, 0) == 0) {
19351968
InitializeCriticalSection(&p->cs);
1936-
InterlockedExchange(&p->init, 2);
1969+
tcc_sem_store(&p->init, 2);
19371970
} else {
1938-
while (InterlockedCompareExchange(&p->init, 2, 2) != 2)
1971+
/* On tcc/arm64, __atomic_load maps to the acquire helper path. */
1972+
while (tcc_sem_load(&p->init) != 2)
19391973
Sleep(0);
19401974
}
19411975
EnterCriticalSection(&p->cs);

0 commit comments

Comments
 (0)