Make lib/stdatomic.c gcc compatible
This commit is contained in:
parent
0f0f701212
commit
f8e50d23f5
2 changed files with 26 additions and 9 deletions
|
@ -14,40 +14,50 @@
|
||||||
#define __ATOMIC_SEQ_CST 5
|
#define __ATOMIC_SEQ_CST 5
|
||||||
|
|
||||||
#define ATOMIC_X86_COMPARE_EXCHANGE(TYPE, MODE, SUFFIX) \
|
#define ATOMIC_X86_COMPARE_EXCHANGE(TYPE, MODE, SUFFIX) \
|
||||||
bool __atomic_compare_exchange_##MODE(_Atomic(TYPE) *atom, TYPE *ref, TYPE xchg) \
|
bool __atomic_compare_exchange_##MODE \
|
||||||
|
(volatile void *atom, void *ref, TYPE xchg, \
|
||||||
|
bool weak, int success_memorder, int failure_memorder) \
|
||||||
{ \
|
{ \
|
||||||
TYPE rv; \
|
TYPE rv; \
|
||||||
TYPE cmp = *ref; \
|
TYPE cmp = *(TYPE *)ref; \
|
||||||
asm volatile( \
|
asm volatile( \
|
||||||
"lock cmpxchg" SUFFIX " %2,%1\n" \
|
"lock cmpxchg" SUFFIX " %2,%1\n" \
|
||||||
: "=a" (rv), "+m" (*atom) \
|
: "=a" (rv), "+m" (*(TYPE *)atom) \
|
||||||
: "q" (xchg), "0" (cmp) \
|
: "q" (xchg), "0" (cmp) \
|
||||||
: "memory" \
|
: "memory" \
|
||||||
); \
|
); \
|
||||||
*ref = rv; \
|
*(TYPE *)ref = rv; \
|
||||||
return (rv == cmp); \
|
return (rv == cmp); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ATOMIC_X86_LOAD(TYPE, MODE) \
|
#define ATOMIC_X86_LOAD(TYPE, MODE) \
|
||||||
TYPE __atomic_load_##MODE(const _Atomic(TYPE) *atom) \
|
TYPE __atomic_load_##MODE(const volatile void *atom, int memorder) \
|
||||||
{ \
|
{ \
|
||||||
return *(volatile TYPE *)atom; \
|
return *(volatile TYPE *)atom; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ATOMIC_X86_STORE(TYPE, MODE) \
|
#define ATOMIC_X86_STORE(TYPE, MODE) \
|
||||||
void __atomic_store_##MODE(_Atomic(TYPE) *atom, TYPE value) \
|
void __atomic_store_##MODE(volatile void *atom, TYPE value, int memorder) \
|
||||||
{ \
|
{ \
|
||||||
*(volatile TYPE *)atom = value; \
|
*(volatile TYPE *)atom = value; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#define ATOMIC_LOAD(t,a,b,c) t b; __atomic_load((t *)a, (t *)&b, c)
|
||||||
|
#define COMPARE_EXCHANGE(t,a,b,c,d,e,f) __atomic_compare_exchange((t *)a,b,&c,d,e,f)
|
||||||
|
#else
|
||||||
|
#define ATOMIC_LOAD(t,a,b,c) t b = __atomic_load((t *)a, c)
|
||||||
|
#define COMPARE_EXCHANGE(t,a,b,c,d,e,f) __atomic_compare_exchange((t *)a,b,c,d,e,f)
|
||||||
|
#endif
|
||||||
|
|
||||||
#define ATOMIC_GEN_OP(TYPE, MODE, NAME, OP) \
|
#define ATOMIC_GEN_OP(TYPE, MODE, NAME, OP) \
|
||||||
TYPE __atomic_##NAME##_##MODE(_Atomic(TYPE) *atom, TYPE value) \
|
TYPE __atomic_##NAME##_##MODE(volatile void *atom, TYPE value, int memorder) \
|
||||||
{ \
|
{ \
|
||||||
TYPE xchg; \
|
TYPE xchg; \
|
||||||
TYPE cmp = __atomic_load(atom, __ATOMIC_RELAXED); \
|
ATOMIC_LOAD(TYPE, atom, cmp, __ATOMIC_RELAXED); \
|
||||||
do { \
|
do { \
|
||||||
xchg = (OP); \
|
xchg = (OP); \
|
||||||
} while (!__atomic_compare_exchange(atom, &cmp, xchg, true, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)); \
|
} while (!COMPARE_EXCHANGE(TYPE, atom, &cmp, xchg, true, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)); \
|
||||||
return cmp; \
|
return cmp; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
7
tccgen.c
7
tccgen.c
|
@ -5835,6 +5835,13 @@ static void parse_atomic(int atok)
|
||||||
|
|
||||||
vpush(&ct);
|
vpush(&ct);
|
||||||
PUT_R_RET(vtop, ct.t);
|
PUT_R_RET(vtop, ct.t);
|
||||||
|
if (ct.t == VT_BOOL) {
|
||||||
|
#ifdef PROMOTE_RET
|
||||||
|
vtop->r |= BFVAL(VT_MUSTCAST, 1);
|
||||||
|
#else
|
||||||
|
vtop->type.t = VT_INT;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ST_FUNC void unary(void)
|
ST_FUNC void unary(void)
|
||||||
|
|
Loading…
Reference in a new issue