mirror of
https://github.com/mirror/tinycc.git
synced 2024-12-26 03:50:07 +08:00
125 lines
3.7 KiB
C
125 lines
3.7 KiB
C
// for libtcc1, avoid including files that are not part of tcc
|
|
// #include <stdint.h>
|
|
#define uint8_t unsigned char
|
|
#define uint16_t unsigned short
|
|
#define uint32_t unsigned int
|
|
#define uint64_t unsigned long long
|
|
#define bool _Bool
|
|
#define true 1
|
|
#define __ATOMIC_RELAXED 0
|
|
#define __ATOMIC_CONSUME 1
|
|
#define __ATOMIC_ACQUIRE 2
|
|
#define __ATOMIC_RELEASE 3
|
|
#define __ATOMIC_ACQ_REL 4
|
|
#define __ATOMIC_SEQ_CST 5
|
|
|
|
#define ATOMIC_X86_COMPARE_EXCHANGE(TYPE, MODE, SUFFIX) \
|
|
bool __atomic_compare_exchange_##MODE \
|
|
(volatile void *atom, void *ref, TYPE xchg, \
|
|
bool weak, int success_memorder, int failure_memorder) \
|
|
{ \
|
|
TYPE rv; \
|
|
TYPE cmp = *(TYPE *)ref; \
|
|
asm volatile( \
|
|
"lock cmpxchg" SUFFIX " %2,%1\n" \
|
|
: "=a" (rv), "+m" (*(TYPE *)atom) \
|
|
: "q" (xchg), "0" (cmp) \
|
|
: "memory" \
|
|
); \
|
|
*(TYPE *)ref = rv; \
|
|
return (rv == cmp); \
|
|
}
|
|
|
|
#define ATOMIC_X86_LOAD(TYPE, MODE) \
|
|
TYPE __atomic_load_##MODE(const volatile void *atom, int memorder) \
|
|
{ \
|
|
return *(volatile TYPE *)atom; \
|
|
}
|
|
|
|
#define ATOMIC_X86_STORE(TYPE, MODE) \
|
|
void __atomic_store_##MODE(volatile void *atom, TYPE value, int memorder) \
|
|
{ \
|
|
*(volatile TYPE *)atom = value; \
|
|
}
|
|
|
|
/* Some tcc targets set __GNUC__ */
|
|
#if defined(__GNUC__) && !defined(__TINYC__)
|
|
#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) \
|
|
TYPE __atomic_##NAME##_##MODE(volatile void *atom, TYPE value, int memorder) \
|
|
{ \
|
|
TYPE xchg; \
|
|
ATOMIC_LOAD(TYPE, atom, cmp, __ATOMIC_RELAXED); \
|
|
do { \
|
|
xchg = (OP); \
|
|
} while (!COMPARE_EXCHANGE(TYPE, atom, &cmp, xchg, true, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)); \
|
|
return cmp; \
|
|
}
|
|
|
|
#define ATOMIC_EXCHANGE(TYPE, MODE) \
|
|
ATOMIC_GEN_OP(TYPE, MODE, exchange, value)
|
|
#define ATOMIC_FETCH_ADD(TYPE, MODE) \
|
|
ATOMIC_GEN_OP(TYPE, MODE, fetch_add, (cmp + value))
|
|
#define ATOMIC_FETCH_SUB(TYPE, MODE) \
|
|
ATOMIC_GEN_OP(TYPE, MODE, fetch_sub, (cmp - value))
|
|
#define ATOMIC_FETCH_AND(TYPE, MODE) \
|
|
ATOMIC_GEN_OP(TYPE, MODE, fetch_and, (cmp & value))
|
|
#define ATOMIC_FETCH_OR(TYPE, MODE) \
|
|
ATOMIC_GEN_OP(TYPE, MODE, fetch_or, (cmp | value))
|
|
#define ATOMIC_FETCH_XOR(TYPE, MODE) \
|
|
ATOMIC_GEN_OP(TYPE, MODE, fetch_xor, (cmp ^ value))
|
|
|
|
ATOMIC_X86_STORE(uint8_t, 1)
|
|
ATOMIC_X86_STORE(uint16_t, 2)
|
|
ATOMIC_X86_STORE(uint32_t, 4)
|
|
|
|
ATOMIC_X86_LOAD(uint8_t, 1)
|
|
ATOMIC_X86_LOAD(uint16_t, 2)
|
|
ATOMIC_X86_LOAD(uint32_t, 4)
|
|
|
|
ATOMIC_X86_COMPARE_EXCHANGE(uint8_t, 1, "b")
|
|
ATOMIC_X86_COMPARE_EXCHANGE(uint16_t, 2, "w")
|
|
ATOMIC_X86_COMPARE_EXCHANGE(uint32_t, 4, "l")
|
|
|
|
ATOMIC_EXCHANGE(uint8_t, 1)
|
|
ATOMIC_EXCHANGE(uint16_t, 2)
|
|
ATOMIC_EXCHANGE(uint32_t, 4)
|
|
|
|
ATOMIC_FETCH_ADD(uint8_t, 1)
|
|
ATOMIC_FETCH_ADD(uint16_t, 2)
|
|
ATOMIC_FETCH_ADD(uint32_t, 4)
|
|
|
|
ATOMIC_FETCH_SUB(uint8_t, 1)
|
|
ATOMIC_FETCH_SUB(uint16_t, 2)
|
|
ATOMIC_FETCH_SUB(uint32_t, 4)
|
|
|
|
ATOMIC_FETCH_AND(uint8_t, 1)
|
|
ATOMIC_FETCH_AND(uint16_t, 2)
|
|
ATOMIC_FETCH_AND(uint32_t, 4)
|
|
|
|
ATOMIC_FETCH_OR(uint8_t, 1)
|
|
ATOMIC_FETCH_OR(uint16_t, 2)
|
|
ATOMIC_FETCH_OR(uint32_t, 4)
|
|
|
|
ATOMIC_FETCH_XOR(uint8_t, 1)
|
|
ATOMIC_FETCH_XOR(uint16_t, 2)
|
|
ATOMIC_FETCH_XOR(uint32_t, 4)
|
|
|
|
#if defined __x86_64__
|
|
ATOMIC_X86_STORE(uint64_t, 8)
|
|
ATOMIC_X86_LOAD(uint64_t, 8)
|
|
ATOMIC_X86_COMPARE_EXCHANGE(uint64_t, 8, "q")
|
|
ATOMIC_EXCHANGE(uint64_t, 8)
|
|
ATOMIC_FETCH_ADD(uint64_t, 8)
|
|
ATOMIC_FETCH_SUB(uint64_t, 8)
|
|
ATOMIC_FETCH_AND(uint64_t, 8)
|
|
ATOMIC_FETCH_OR(uint64_t, 8)
|
|
ATOMIC_FETCH_XOR(uint64_t, 8)
|
|
#endif
|